mirror of
https://github.com/mathuo/dockview
synced 2025-01-22 17:35:57 +00:00
chore: remove old docs
This commit is contained in:
parent
83b01a9a66
commit
e46a586044
@ -6,41 +6,6 @@
|
|||||||
"packages/dockview"
|
"packages/dockview"
|
||||||
],
|
],
|
||||||
"sandboxes": [
|
"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/editor-gridview",
|
|
||||||
"/packages/docs/sandboxes/events-dockview",
|
|
||||||
"/packages/docs/sandboxes/externaldnd-dockview",
|
|
||||||
"/packages/docs/sandboxes/floatinggroup-dockview",
|
|
||||||
"/packages/docs/sandboxes/fullwidthtab-dockview",
|
|
||||||
"/packages/docs/sandboxes/headeractions-dockview",
|
|
||||||
"/packages/docs/sandboxes/groupcontol-dockview",
|
|
||||||
"/packages/docs/sandboxes/iframe-dockview",
|
|
||||||
"/packages/docs/sandboxes/keyboard-dockview",
|
|
||||||
"/packages/docs/sandboxes/layout-dockview",
|
|
||||||
"/packages/docs/sandboxes/lockedgroup-dockview",
|
|
||||||
"/packages/docs/sandboxes/maximizegroup-dockview",
|
|
||||||
"/packages/docs/sandboxes/nativeapp-dockview",
|
|
||||||
"/packages/docs/sandboxes/nested-dockview",
|
|
||||||
"/packages/docs/sandboxes/popoutgroup-dockview",
|
|
||||||
"/packages/docs/sandboxes/rendering-dockview",
|
|
||||||
"/packages/docs/sandboxes/rendermode-dockview",
|
|
||||||
"/packages/docs/sandboxes/resize-dockview",
|
|
||||||
"/packages/docs/sandboxes/resizecontainer-dockview",
|
|
||||||
"/packages/docs/sandboxes/scrollbars-dockview",
|
|
||||||
"/packages/docs/sandboxes/simple-dockview",
|
|
||||||
"/packages/docs/sandboxes/simple-gridview",
|
|
||||||
"/packages/docs/sandboxes/simple-paneview",
|
|
||||||
"/packages/docs/sandboxes/tabheight-dockview",
|
|
||||||
"/packages/docs/sandboxes/updatetitle-dockview",
|
|
||||||
"/packages/docs/sandboxes/watermark-dockview",
|
|
||||||
"/packages/docs/sandboxes/javascript/fullwidthtab-dockview",
|
|
||||||
"/packages/docs/sandboxes/javascript/simple-dockview",
|
|
||||||
"/packages/docs/sandboxes/javascript/tabheight-dockview",
|
|
||||||
"/packages/docs/sandboxes/javascript/vanilla-dockview"
|
|
||||||
],
|
],
|
||||||
"node": "18"
|
"node": "18"
|
||||||
}
|
}
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "customheader-dockview",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.tsx",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview": "*",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/react": "^18.0.28",
|
|
||||||
"@types/react-dom": "^18.0.11",
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,122 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewDefaultTab,
|
|
||||||
DockviewReact,
|
|
||||||
DockviewReadyEvent,
|
|
||||||
IDockviewPanelHeaderProps,
|
|
||||||
IDockviewPanelProps,
|
|
||||||
} from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
interface CustomProps {
|
|
||||||
valueA: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
default: (props: IDockviewPanelProps<CustomProps>) => {
|
|
||||||
return <div style={{ padding: '20px' }}>{props.api.title}</div>;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const headerComponents = {
|
|
||||||
default: (props: IDockviewPanelHeaderProps<CustomProps>) => {
|
|
||||||
const onContextMenu = (event: React.MouseEvent) => {
|
|
||||||
event.preventDefault();
|
|
||||||
alert(
|
|
||||||
`This custom header was parsed the params ${JSON.stringify(
|
|
||||||
props.params
|
|
||||||
)}`
|
|
||||||
);
|
|
||||||
};
|
|
||||||
return <DockviewDefaultTab onContextMenu={onContextMenu} {...props} />;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const CustomHeadersDockview = (props: { theme?: string }) => {
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_1',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 1',
|
|
||||||
params: {
|
|
||||||
valueA: 'test value',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_2',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 2',
|
|
||||||
params: {
|
|
||||||
valueA: 'test value',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_3',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 3',
|
|
||||||
params: {
|
|
||||||
valueA: 'test value',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_4',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 4',
|
|
||||||
position: { referencePanel: 'panel_3', direction: 'right' },
|
|
||||||
params: {
|
|
||||||
valueA: 'test value',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_5',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 5',
|
|
||||||
position: { referencePanel: 'panel_4', direction: 'within' },
|
|
||||||
params: {
|
|
||||||
valueA: 'test value',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const panel6 = event.api.addPanel({
|
|
||||||
id: 'panel_6',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 6',
|
|
||||||
position: { referencePanel: 'panel_4', direction: 'below' },
|
|
||||||
params: {
|
|
||||||
valueA: 'test value',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
panel6.group.locked = true;
|
|
||||||
panel6.group.header.hidden = true;
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_7',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 7',
|
|
||||||
position: { referencePanel: 'panel_6', direction: 'right' },
|
|
||||||
params: {
|
|
||||||
valueA: 'test value',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_8',
|
|
||||||
component: 'default',
|
|
||||||
|
|
||||||
title: 'Panel 8',
|
|
||||||
position: { referencePanel: 'panel_7', direction: 'within' },
|
|
||||||
params: {
|
|
||||||
valueA: 'test value',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.addGroup();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DockviewReact
|
|
||||||
components={components}
|
|
||||||
defaultTabComponent={headerComponents.default}
|
|
||||||
onReady={onReady}
|
|
||||||
className={`${props.theme || 'dockview-theme-abyss'}`}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CustomHeadersDockview;
|
|
@ -1,20 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "events-dockview",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.tsx",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview": "*",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/react": "^18.0.28",
|
|
||||||
"@types/react-dom": "^18.0.11",
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,346 +0,0 @@
|
|||||||
import {
|
|
||||||
Orientation,
|
|
||||||
DockviewReact,
|
|
||||||
DockviewReadyEvent,
|
|
||||||
DockviewApi,
|
|
||||||
IDockviewPanelProps,
|
|
||||||
} from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
import { Console, Line } from './console';
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
default: (props: IDockviewPanelProps<{ title: string }>) => {
|
|
||||||
return <div style={{ padding: '20px' }}>{props.params.title}</div>;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const EventsDockview = (props: { theme?: string }) => {
|
|
||||||
const [lines, setLines] = React.useState<Line[]>([]);
|
|
||||||
const [checked, setChecked] = React.useState<boolean>(false);
|
|
||||||
|
|
||||||
const [api, setApi] = React.useState<DockviewApi | undefined>();
|
|
||||||
|
|
||||||
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',
|
|
||||||
contentComponent: 'default',
|
|
||||||
params: { title: 'Panel 1' },
|
|
||||||
title: 'panel_1',
|
|
||||||
},
|
|
||||||
panel_2: {
|
|
||||||
id: 'panel_2',
|
|
||||||
contentComponent: 'default',
|
|
||||||
params: { title: 'Panel 2' },
|
|
||||||
title: 'panel_2',
|
|
||||||
},
|
|
||||||
panel_3: {
|
|
||||||
id: 'panel_3',
|
|
||||||
contentComponent: 'default',
|
|
||||||
params: { title: 'Panel 3' },
|
|
||||||
title: 'panel_3',
|
|
||||||
},
|
|
||||||
panel_4: {
|
|
||||||
id: 'panel_4',
|
|
||||||
contentComponent: 'default',
|
|
||||||
params: { title: 'Panel 4' },
|
|
||||||
title: 'panel_4',
|
|
||||||
},
|
|
||||||
panel_5: {
|
|
||||||
id: 'panel_5',
|
|
||||||
contentComponent: 'default',
|
|
||||||
params: { title: 'Panel 5' },
|
|
||||||
title: 'panel_5',
|
|
||||||
},
|
|
||||||
panel_6: {
|
|
||||||
id: 'panel_6',
|
|
||||||
contentComponent: 'default',
|
|
||||||
params: { title: 'Panel 6' },
|
|
||||||
title: 'panel_6',
|
|
||||||
},
|
|
||||||
panel_8: {
|
|
||||||
id: 'panel_8',
|
|
||||||
contentComponent: 'default',
|
|
||||||
params: { title: 'Panel 8' },
|
|
||||||
title: 'panel_8',
|
|
||||||
},
|
|
||||||
panel_7: {
|
|
||||||
id: 'panel_7',
|
|
||||||
contentComponent: 'default',
|
|
||||||
params: { title: 'Panel 7' },
|
|
||||||
title: 'panel_7',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
activeGroup: '80',
|
|
||||||
});
|
|
||||||
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 (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
height: '100%',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<label>
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
checked={checked}
|
|
||||||
onChange={(e) => setChecked(e.target.checked)}
|
|
||||||
/>
|
|
||||||
<span>{'fromJSON'}</span>
|
|
||||||
</label>
|
|
||||||
<button onClick={() => setLines([])}>Clear logs</button>
|
|
||||||
</div>
|
|
||||||
<div style={{ flexGrow: 1 }}>
|
|
||||||
<DockviewReact
|
|
||||||
components={components}
|
|
||||||
onReady={onReady}
|
|
||||||
className={`${props.theme || 'dockview-theme-abyss'}`}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div style={{ height: '200px', paddingTop: '5px' }}>
|
|
||||||
<Console lines={lines} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EventsDockview;
|
|
@ -1,27 +0,0 @@
|
|||||||
.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
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<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
React.useLayoutEffect(() => {
|
|
||||||
if (!ref.current) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ref.current.scrollTop = Math.max(
|
|
||||||
0,
|
|
||||||
ref.current.scrollHeight - ref.current.clientHeight
|
|
||||||
);
|
|
||||||
}, [props.lines]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div ref={ref} className="console-container">
|
|
||||||
{props.lines.map((line, i) => {
|
|
||||||
return (
|
|
||||||
<div key={i} className="console-line">
|
|
||||||
<span className="console-line-timestamp">
|
|
||||||
{formatTime(line.timestamp)}
|
|
||||||
</span>
|
|
||||||
<span className="console-line-text" style={line.css}>
|
|
||||||
{line.text}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,20 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "focus-dockview",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.tsx",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview": "*",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/react": "^18.0.28",
|
|
||||||
"@types/react-dom": "^18.0.11",
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,125 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewApi,
|
|
||||||
DockviewReact,
|
|
||||||
DockviewReadyEvent,
|
|
||||||
IDockviewPanelProps,
|
|
||||||
} from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
default: (props: IDockviewPanelProps) => {
|
|
||||||
React.useEffect(() => {
|
|
||||||
const d1 = props.api.onWillFocus((event) => {
|
|
||||||
console.log('willFocus');
|
|
||||||
});
|
|
||||||
|
|
||||||
const d2 = props.api.onDidActiveChange((event) => {
|
|
||||||
console.log(props.api.title, event, 'active');
|
|
||||||
});
|
|
||||||
|
|
||||||
const d3 = props.api.onDidActiveGroupChange((event) => {
|
|
||||||
console.log(
|
|
||||||
props.api.title,
|
|
||||||
props.api.group.api.isActive,
|
|
||||||
'active-group'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const d4 = props.api.onDidGroupChange((event) => {
|
|
||||||
console.log(
|
|
||||||
props.api.title,
|
|
||||||
props.api.group.id,
|
|
||||||
'group-change'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
d1.dispose();
|
|
||||||
d2.dispose();
|
|
||||||
d3.dispose();
|
|
||||||
};
|
|
||||||
}, [props.api]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ padding: '20px', color: 'white' }}>
|
|
||||||
{props.api.title}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const App: React.FC = (props: { theme?: string }) => {
|
|
||||||
const [api, setApi] = React.useState<DockviewApi>();
|
|
||||||
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
|
||||||
setApi(event.api);
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_1',
|
|
||||||
title: 'Panel 1',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_2',
|
|
||||||
title: 'Panel 2',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
// event.api.onDidAddPanel((event) => {
|
|
||||||
// console.log('add panel', event);
|
|
||||||
// });
|
|
||||||
// event.api.onDidActivePanelChange((event) => {
|
|
||||||
// console.log('active panel', event);
|
|
||||||
// });
|
|
||||||
// event.api.onDidRemovePanel((event) => {
|
|
||||||
// console.log('remove panel', event);
|
|
||||||
// });
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{ height: '100%', display: 'flex', flexDirection: 'column' }}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
api?.getPanel('panel_1')?.focus();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{'Focus Panel 1'}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
api?.getPanel('panel_2')?.focus();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{'Focus Panel 2'}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
api?.getPanel('panel_1')?.api.setActive();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{'Active Panel 1'}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
api?.getPanel('panel_2')?.api.setActive();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{'Active Panel 2'}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div style={{ flexGrow: 1 }}>
|
|
||||||
<DockviewReact
|
|
||||||
components={components}
|
|
||||||
onReady={onReady}
|
|
||||||
className={props.theme || 'dockview-theme-abyss'}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
@ -1,20 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "javascript-simple-dockview",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.ts",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview-core": "*"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,120 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewComponent,
|
|
||||||
IContentRenderer,
|
|
||||||
IGroupPanelInitParameters,
|
|
||||||
PanelUpdateEvent,
|
|
||||||
Parameters,
|
|
||||||
} from 'dockview-core';
|
|
||||||
|
|
||||||
class DefaultPanel implements IContentRenderer {
|
|
||||||
private _element: HTMLElement;
|
|
||||||
|
|
||||||
get element(): HTMLElement {
|
|
||||||
return this._element;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this._element = document.createElement('div');
|
|
||||||
this._element.style.padding = '20px';
|
|
||||||
this._element.style.color = 'white';
|
|
||||||
}
|
|
||||||
|
|
||||||
init(params: IGroupPanelInitParameters): void {
|
|
||||||
this._element.textContent = params.params.title;
|
|
||||||
}
|
|
||||||
|
|
||||||
update(event: PanelUpdateEvent<Parameters>): void {
|
|
||||||
this._element.textContent = event.params.title;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function attach(parent: HTMLElement): {
|
|
||||||
dispose: () => void;
|
|
||||||
} {
|
|
||||||
const element = document.createElement('div');
|
|
||||||
element.className = 'dockview-theme-abyss';
|
|
||||||
element.style.height = '100%';
|
|
||||||
element.style.width = '100%';
|
|
||||||
|
|
||||||
const dockview = new DockviewComponent({
|
|
||||||
components: {
|
|
||||||
default: DefaultPanel,
|
|
||||||
},
|
|
||||||
parentElement: element,
|
|
||||||
});
|
|
||||||
|
|
||||||
parent.appendChild(element);
|
|
||||||
|
|
||||||
const { clientWidth, clientHeight } = parent;
|
|
||||||
dockview.layout(clientWidth, clientHeight);
|
|
||||||
|
|
||||||
const panel = dockview.addPanel({
|
|
||||||
id: 'panel_1',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Panel 1',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
panel.group.locked = true;
|
|
||||||
panel.group.header.hidden = true;
|
|
||||||
|
|
||||||
dockview.addPanel({
|
|
||||||
id: 'panel_2',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Panel 2',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
dockview.addPanel({
|
|
||||||
id: 'panel_3',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Panel 3',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
dockview.addPanel({
|
|
||||||
id: 'panel_4',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Panel 4',
|
|
||||||
},
|
|
||||||
position: { referencePanel: 'panel_1', direction: 'right' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const panel5 = dockview.addPanel({
|
|
||||||
id: 'panel_5',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Panel 5',
|
|
||||||
},
|
|
||||||
position: { referencePanel: 'panel_3', direction: 'right' },
|
|
||||||
});
|
|
||||||
|
|
||||||
dockview.addPanel({
|
|
||||||
id: 'panel_6',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Panel 6',
|
|
||||||
},
|
|
||||||
position: { referencePanel: 'panel_5', direction: 'below' },
|
|
||||||
});
|
|
||||||
|
|
||||||
dockview.addPanel({
|
|
||||||
id: 'panel_7',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Panel 7',
|
|
||||||
},
|
|
||||||
position: { referencePanel: 'panel_6', direction: 'right' },
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
dispose: () => {
|
|
||||||
dockview.dispose();
|
|
||||||
element.remove();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
import './styles.css';
|
|
||||||
import 'dockview-core/dist/styles/dockview.css';
|
|
||||||
|
|
||||||
import { attach } from './app';
|
|
||||||
|
|
||||||
const rootElement = document.getElementById('root');
|
|
||||||
|
|
||||||
if (rootElement) {
|
|
||||||
attach(rootElement);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "javascript-tabheight-dockview",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.ts",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview-core": "*"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,3 +0,0 @@
|
|||||||
.skinny-tabs {
|
|
||||||
--dv-tabs-and-actions-container-height: 20px;
|
|
||||||
}
|
|
@ -1,110 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewComponent,
|
|
||||||
IContentRenderer,
|
|
||||||
IGroupPanelInitParameters,
|
|
||||||
PanelUpdateEvent,
|
|
||||||
Parameters,
|
|
||||||
} from 'dockview-core';
|
|
||||||
import './app.scss';
|
|
||||||
|
|
||||||
class DefaultPanel implements IContentRenderer {
|
|
||||||
private _element: HTMLElement;
|
|
||||||
|
|
||||||
get element(): HTMLElement {
|
|
||||||
return this._element;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this._element = document.createElement('div');
|
|
||||||
this._element.style.padding = '20px';
|
|
||||||
this._element.style.color = 'white';
|
|
||||||
}
|
|
||||||
|
|
||||||
init(params: IGroupPanelInitParameters): void {
|
|
||||||
this._element.textContent = params.params.title;
|
|
||||||
}
|
|
||||||
|
|
||||||
update(event: PanelUpdateEvent<Parameters>): void {
|
|
||||||
this._element.textContent = event.params.title;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function attach(parent: HTMLElement): {
|
|
||||||
dispose: () => void;
|
|
||||||
} {
|
|
||||||
const element = document.createElement('div');
|
|
||||||
element.className = 'dockview-theme-abyss skinny-tabs';
|
|
||||||
element.style.height = '100%';
|
|
||||||
element.style.width = '100%';
|
|
||||||
|
|
||||||
const dockview = new DockviewComponent({
|
|
||||||
components: {
|
|
||||||
default: DefaultPanel,
|
|
||||||
},
|
|
||||||
parentElement: element,
|
|
||||||
});
|
|
||||||
|
|
||||||
parent.appendChild(element);
|
|
||||||
|
|
||||||
const { clientWidth, clientHeight } = parent;
|
|
||||||
dockview.layout(clientWidth, clientHeight);
|
|
||||||
|
|
||||||
dockview.addPanel({
|
|
||||||
id: 'panel_1',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Panel 1',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
dockview.addPanel({
|
|
||||||
id: 'panel_2',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Panel 2',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
dockview.addPanel({
|
|
||||||
id: 'panel_3',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Panel 3',
|
|
||||||
},
|
|
||||||
position: { referencePanel: 'panel_1', direction: 'right' },
|
|
||||||
});
|
|
||||||
|
|
||||||
dockview.addPanel({
|
|
||||||
id: 'panel_4',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Panel 4',
|
|
||||||
},
|
|
||||||
position: { referencePanel: 'panel_3', direction: 'right' },
|
|
||||||
});
|
|
||||||
|
|
||||||
dockview.addPanel({
|
|
||||||
id: 'panel_5',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Panel 5',
|
|
||||||
},
|
|
||||||
position: { referencePanel: 'panel_4', direction: 'below' },
|
|
||||||
});
|
|
||||||
|
|
||||||
dockview.addPanel({
|
|
||||||
id: 'panel_6',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Panel 6',
|
|
||||||
},
|
|
||||||
position: { referencePanel: 'panel_5', direction: 'right' },
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
dispose: () => {
|
|
||||||
dockview.dispose();
|
|
||||||
element.remove();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
import './styles.css';
|
|
||||||
import 'dockview-core/dist/styles/dockview.css';
|
|
||||||
|
|
||||||
import { attach } from './app';
|
|
||||||
|
|
||||||
const rootElement = document.getElementById('root');
|
|
||||||
|
|
||||||
if (rootElement) {
|
|
||||||
attach(rootElement);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "javascript-vanilla-dockview",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.ts",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview-core": "*"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,80 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewComponent,
|
|
||||||
IContentRenderer,
|
|
||||||
IGroupPanelInitParameters,
|
|
||||||
} from 'dockview-core';
|
|
||||||
|
|
||||||
class DefaultPanel implements IContentRenderer {
|
|
||||||
private _element: HTMLElement;
|
|
||||||
|
|
||||||
get element(): HTMLElement {
|
|
||||||
return this._element;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this._element = document.createElement('div');
|
|
||||||
}
|
|
||||||
|
|
||||||
init(params: IGroupPanelInitParameters): void {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function attach(parent: HTMLElement): {
|
|
||||||
dispose: () => void;
|
|
||||||
} {
|
|
||||||
const element = document.createElement('div');
|
|
||||||
element.className = 'dockview-theme-abyss';
|
|
||||||
element.style.height = '100%';
|
|
||||||
element.style.width = '100%';
|
|
||||||
|
|
||||||
const dockview = new DockviewComponent({
|
|
||||||
components: {
|
|
||||||
default: DefaultPanel,
|
|
||||||
},
|
|
||||||
parentElement: element,
|
|
||||||
});
|
|
||||||
|
|
||||||
parent.appendChild(element);
|
|
||||||
|
|
||||||
const panel1 = dockview.addPanel({
|
|
||||||
id: 'panel_1',
|
|
||||||
title: 'Panel 1',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
const panel2 = dockview.addPanel({
|
|
||||||
id: 'panel_2',
|
|
||||||
title: 'Panel 2',
|
|
||||||
component: 'default',
|
|
||||||
position: {
|
|
||||||
referencePanel: panel1,
|
|
||||||
direction: 'right',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const panel3 = dockview.addPanel({
|
|
||||||
id: 'panel_3',
|
|
||||||
title: 'Panel 3',
|
|
||||||
component: 'default',
|
|
||||||
position: {
|
|
||||||
referenceGroup: panel2.group,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const pane4 = dockview.addPanel({
|
|
||||||
id: 'panel_4',
|
|
||||||
title: 'Panel 4',
|
|
||||||
component: 'default',
|
|
||||||
position: {
|
|
||||||
direction: 'below',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
dispose: () => {
|
|
||||||
dockview.dispose();
|
|
||||||
element.remove();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
import './styles.css';
|
|
||||||
import 'dockview-core/dist/styles/dockview.css';
|
|
||||||
|
|
||||||
import { attach } from './app';
|
|
||||||
|
|
||||||
const rootElement = document.getElementById('root');
|
|
||||||
|
|
||||||
if (rootElement) {
|
|
||||||
attach(rootElement);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "lockedgroup-dockview",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.tsx",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview": "*",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/react": "^18.0.28",
|
|
||||||
"@types/react-dom": "^18.0.11",
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,71 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewReact,
|
|
||||||
DockviewReadyEvent,
|
|
||||||
IDockviewPanelProps,
|
|
||||||
} from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
default: (props: IDockviewPanelProps<{ title: string }>) => {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: '20px', color: 'white' }}>
|
|
||||||
{props.params.title}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const App: React.FC = (props: { theme?: string }) => {
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
|
||||||
const panel1 = event.api.addPanel({
|
|
||||||
id: 'locked1',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Locked',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
panel1.group.locked = true;
|
|
||||||
panel1.group.header.hidden = true;
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'Drag me',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: '',
|
|
||||||
},
|
|
||||||
position: { referencePanel: 'locked1', direction: 'right' },
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'Drag me too',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: '',
|
|
||||||
},
|
|
||||||
position: { referencePanel: 'Drag me', direction: 'right' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const panel3 = event.api.addPanel({
|
|
||||||
id: 'locked2',
|
|
||||||
component: 'default',
|
|
||||||
params: {
|
|
||||||
title: 'Locked with no drop target',
|
|
||||||
},
|
|
||||||
position: { referencePanel: 'Drag me too', direction: 'right' },
|
|
||||||
});
|
|
||||||
|
|
||||||
panel3.group.locked = 'no-drop-target';
|
|
||||||
panel3.group.header.hidden = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DockviewReact
|
|
||||||
components={components}
|
|
||||||
onReady={onReady}
|
|
||||||
className={props.theme || 'dockview-theme-abyss'}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
@ -1,20 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "nested-dockview",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.tsx",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview": "*",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/react": "^18.0.28",
|
|
||||||
"@types/react-dom": "^18.0.11",
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,12 +0,0 @@
|
|||||||
.nested-dockview {
|
|
||||||
position: relative;
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
left: 0px;
|
|
||||||
height: 1px;
|
|
||||||
width: 100%;
|
|
||||||
background-color: var(--dv-separator-border);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,95 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewDndOverlayEvent,
|
|
||||||
DockviewDropEvent,
|
|
||||||
DockviewReact,
|
|
||||||
DockviewReadyEvent,
|
|
||||||
IDockviewPanelProps,
|
|
||||||
} from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
import './app.scss';
|
|
||||||
|
|
||||||
const InnerDockview = () => {
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_1',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_2',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_3',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DockviewReact
|
|
||||||
onReady={onReady}
|
|
||||||
components={components}
|
|
||||||
className="nested-dockview"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
default: (props: IDockviewPanelProps<{ title: string }>) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: '100%',
|
|
||||||
padding: '20px',
|
|
||||||
background: 'var(--dv-group-view-background-color)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{props.params.title}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
innerDockview: InnerDockview,
|
|
||||||
};
|
|
||||||
|
|
||||||
const NestedDockview = (props: { theme?: string }) => {
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_1',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_2',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_3',
|
|
||||||
component: 'innerDockview',
|
|
||||||
position: { referencePanel: 'panel_2', direction: 'right' },
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const showDndOverlay = (event: DockviewDndOverlayEvent) => {
|
|
||||||
// console.log(event.getData());
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDidDrop = (event: DockviewDropEvent) => {
|
|
||||||
// event.getData();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DockviewReact
|
|
||||||
onReady={onReady}
|
|
||||||
components={components}
|
|
||||||
className={`${props.theme || 'dockview-theme-abyss'}`}
|
|
||||||
showDndOverlay={showDndOverlay}
|
|
||||||
onDidDrop={onDidDrop}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default NestedDockview;
|
|
@ -1,20 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "dockview.constraints",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.tsx",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview": "*",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/react": "^18.0.28",
|
|
||||||
"@types/react-dom": "^18.0.11",
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,148 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewApi,
|
|
||||||
DockviewReact,
|
|
||||||
DockviewReadyEvent,
|
|
||||||
GridConstraintChangeEvent,
|
|
||||||
IDockviewPanelProps,
|
|
||||||
} from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
default: (props: IDockviewPanelProps) => {
|
|
||||||
const [contraints, setContraints] =
|
|
||||||
React.useState<GridConstraintChangeEvent | null>(null);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
props.api.group.api.onDidConstraintsChange((event) => {
|
|
||||||
setContraints(event);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onClick = () => {
|
|
||||||
props.api.group.api.setConstraints({
|
|
||||||
maximumWidth: 300,
|
|
||||||
maximumHeight: 300,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: '100%',
|
|
||||||
padding: '20px',
|
|
||||||
background: 'var(--dv-group-view-background-color)',
|
|
||||||
color: 'white',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<button onClick={onClick}>Set</button>
|
|
||||||
{contraints && (
|
|
||||||
<div style={{ fontSize: '13px' }}>
|
|
||||||
{typeof contraints.maximumHeight === 'number' && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
border: '1px solid grey',
|
|
||||||
margin: '2px',
|
|
||||||
padding: '1px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{ color: 'grey' }}
|
|
||||||
>{`Maximum Height: `}</span>
|
|
||||||
<span>{`${contraints.maximumHeight}px`}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{typeof contraints.minimumHeight === 'number' && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
border: '1px solid grey',
|
|
||||||
margin: '2px',
|
|
||||||
padding: '1px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{ color: 'grey' }}
|
|
||||||
>{`Minimum Height: `}</span>
|
|
||||||
<span>{`${contraints.minimumHeight}px`}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{typeof contraints.maximumWidth === 'number' && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
border: '1px solid grey',
|
|
||||||
margin: '2px',
|
|
||||||
padding: '1px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{ color: 'grey' }}
|
|
||||||
>{`Maximum Width: `}</span>
|
|
||||||
<span>{`${contraints.maximumWidth}px`}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{typeof contraints.minimumWidth === 'number' && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
border: '1px solid grey',
|
|
||||||
margin: '2px',
|
|
||||||
padding: '1px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{ color: 'grey' }}
|
|
||||||
>{`Minimum Width: `}</span>
|
|
||||||
<span>{`${contraints.minimumWidth}px`}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const App = (props: { theme?: string }) => {
|
|
||||||
const [api, setApi] = React.useState<DockviewApi>();
|
|
||||||
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
|
||||||
const panel1 = event.api.addPanel({
|
|
||||||
id: 'panel_1',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
const panel2 = event.api.addPanel({
|
|
||||||
id: 'panel_2',
|
|
||||||
component: 'default',
|
|
||||||
position: {
|
|
||||||
referencePanel: panel1,
|
|
||||||
direction: 'right',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const panel3 = event.api.addPanel({
|
|
||||||
id: 'panel_3',
|
|
||||||
component: 'default',
|
|
||||||
position: {
|
|
||||||
referencePanel: panel2,
|
|
||||||
direction: 'right',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const panel4 = event.api.addPanel({
|
|
||||||
id: 'panel_4',
|
|
||||||
component: 'default',
|
|
||||||
position: {
|
|
||||||
direction: 'below',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DockviewReact
|
|
||||||
onReady={onReady}
|
|
||||||
components={components}
|
|
||||||
className={`${props.theme || 'dockview-theme-abyss'}`}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
@ -1,20 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "dockview.demo",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.tsx",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview": "*",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0",
|
|
||||||
"uuid": "^9.0.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/react": "^18.0.28",
|
|
||||||
"@types/react-dom": "^18.0.11",
|
|
||||||
"@types/uuid": "^9.0.0",
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,96 +0,0 @@
|
|||||||
.group-control {
|
|
||||||
.action {
|
|
||||||
padding: 4px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 18px;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-radius: 2px;
|
|
||||||
background-color: var(--dv-icon-hover-background-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.data-table {
|
|
||||||
table {
|
|
||||||
font-size: 11px;
|
|
||||||
th {
|
|
||||||
padding: 0px 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-container {
|
|
||||||
display: flex;
|
|
||||||
padding: 4px 0px;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
button {
|
|
||||||
height: 25px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: #1c254a;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
outline: 1px solid #4c65d4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: #222e62;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-button {
|
|
||||||
margin: 0px 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-action {
|
|
||||||
margin: 0px 4px;
|
|
||||||
// display: flex;
|
|
||||||
|
|
||||||
.selected {
|
|
||||||
background-color: #4864dc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-group {
|
|
||||||
button {
|
|
||||||
margin-right: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.demo-button {
|
|
||||||
min-width: 50px;
|
|
||||||
padding: 0px 2px;
|
|
||||||
border-radius: 0px;
|
|
||||||
display: flex;
|
|
||||||
flex-grow: 1;
|
|
||||||
align-items: center;
|
|
||||||
outline: 1px solid #4c65d4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.demo-icon-button {
|
|
||||||
outline: 1px solid #4c65d4;
|
|
||||||
flex-grow: 1;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
border-radius: 0px;
|
|
||||||
padding: 0px 4px;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
color: gray;
|
|
||||||
cursor: help;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,431 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewDefaultTab,
|
|
||||||
DockviewReact,
|
|
||||||
DockviewReadyEvent,
|
|
||||||
IDockviewPanelHeaderProps,
|
|
||||||
IDockviewPanelProps,
|
|
||||||
DockviewApi,
|
|
||||||
} from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
import './app.scss';
|
|
||||||
import { defaultConfig } from './defaultLayout';
|
|
||||||
import { GridActions } from './gridActions';
|
|
||||||
import { PanelActions } from './panelActions';
|
|
||||||
import { GroupActions } from './groupActions';
|
|
||||||
import { LeftControls, PrefixHeaderControls, RightControls } from './controls';
|
|
||||||
import { Table, usePanelApiMetadata } from './debugPanel';
|
|
||||||
|
|
||||||
const DebugContext = React.createContext<boolean>(false);
|
|
||||||
|
|
||||||
const Option = (props: {
|
|
||||||
title: string;
|
|
||||||
onClick: () => void;
|
|
||||||
value: string;
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<span>{`${props.title}: `}</span>
|
|
||||||
<button onClick={props.onClick}>{props.value}</button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
default: (props: IDockviewPanelProps) => {
|
|
||||||
const isDebug = React.useContext(DebugContext);
|
|
||||||
const metadata = usePanelApiMetadata(props.api);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: '100%',
|
|
||||||
overflow: 'auto',
|
|
||||||
position: 'relative',
|
|
||||||
padding: 5,
|
|
||||||
border: isDebug ? '2px dashed orange' : '',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
position: 'absolute',
|
|
||||||
top: '50%',
|
|
||||||
left: '50%',
|
|
||||||
transform: 'translate(-50%,-50%)',
|
|
||||||
pointerEvents: 'none',
|
|
||||||
fontSize: '42px',
|
|
||||||
opacity: 0.5,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{props.api.title}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
{isDebug && (
|
|
||||||
<div style={{ fontSize: '0.8em' }}>
|
|
||||||
<Option
|
|
||||||
title="Panel Rendering Mode"
|
|
||||||
value={metadata.renderer.value}
|
|
||||||
onClick={() =>
|
|
||||||
props.api.setRenderer(
|
|
||||||
props.api.renderer === 'always'
|
|
||||||
? 'onlyWhenVisible'
|
|
||||||
: 'always'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Table data={metadata} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
nested: (props: IDockviewPanelProps) => {
|
|
||||||
return (
|
|
||||||
<DockviewReact
|
|
||||||
components={components}
|
|
||||||
onReady={(event: DockviewReadyEvent) => {
|
|
||||||
event.api.addPanel({ id: 'panel_1', component: 'default' });
|
|
||||||
event.api.addPanel({ id: 'panel_2', component: 'default' });
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_3',
|
|
||||||
component: 'default',
|
|
||||||
floating: true,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
className={'dockview-theme-abyss'}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
iframe: (props: IDockviewPanelProps) => {
|
|
||||||
return (
|
|
||||||
<iframe
|
|
||||||
onMouseDown={() => {
|
|
||||||
if (!props.api.isActive) {
|
|
||||||
props.api.setActive();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
}}
|
|
||||||
src="https://dockview.dev"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const headerComponents = {
|
|
||||||
default: (props: IDockviewPanelHeaderProps) => {
|
|
||||||
const onContextMenu = (event: React.MouseEvent) => {
|
|
||||||
event.preventDefault();
|
|
||||||
alert('context menu');
|
|
||||||
};
|
|
||||||
return <DockviewDefaultTab onContextMenu={onContextMenu} {...props} />;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const colors = [
|
|
||||||
'rgba(255,0,0,0.2)',
|
|
||||||
'rgba(0,255,0,0.2)',
|
|
||||||
'rgba(0,0,255,0.2)',
|
|
||||||
'rgba(255,255,0,0.2)',
|
|
||||||
'rgba(0,255,255,0.2)',
|
|
||||||
'rgba(255,0,255,0.2)',
|
|
||||||
];
|
|
||||||
let count = 0;
|
|
||||||
|
|
||||||
const WatermarkComponent = () => {
|
|
||||||
return <div>custom watermark</div>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const DockviewDemo = (props: { theme?: string }) => {
|
|
||||||
const [logLines, setLogLines] = React.useState<
|
|
||||||
{ text: string; timestamp?: Date; backgroundColor?: string }[]
|
|
||||||
>([]);
|
|
||||||
|
|
||||||
const [panels, setPanels] = React.useState<string[]>([]);
|
|
||||||
const [groups, setGroups] = React.useState<string[]>([]);
|
|
||||||
const [api, setApi] = React.useState<DockviewApi>();
|
|
||||||
|
|
||||||
const [activePanel, setActivePanel] = React.useState<string>();
|
|
||||||
const [activeGroup, setActiveGroup] = React.useState<string>();
|
|
||||||
|
|
||||||
const [pending, setPending] = React.useState<
|
|
||||||
{ text: string; timestamp?: Date }[]
|
|
||||||
>([]);
|
|
||||||
|
|
||||||
const addLogLine = (message: string) => {
|
|
||||||
setPending((line) => [
|
|
||||||
{ text: message, timestamp: new Date() },
|
|
||||||
...line,
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
React.useLayoutEffect(() => {
|
|
||||||
if (pending.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const color = colors[count++ % colors.length];
|
|
||||||
setLogLines((lines) => [
|
|
||||||
...pending.map((_) => ({ ..._, backgroundColor: color })),
|
|
||||||
...lines,
|
|
||||||
]);
|
|
||||||
setPending([]);
|
|
||||||
}, [pending]);
|
|
||||||
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
|
||||||
setApi(event.api);
|
|
||||||
|
|
||||||
event.api.onDidAddPanel((event) => {
|
|
||||||
setPanels((_) => [..._, event.id]);
|
|
||||||
addLogLine(`Panel Added ${event.id}`);
|
|
||||||
});
|
|
||||||
event.api.onDidActivePanelChange((event) => {
|
|
||||||
setActivePanel(event?.id);
|
|
||||||
addLogLine(`Panel Activated ${event?.id}`);
|
|
||||||
});
|
|
||||||
event.api.onDidRemovePanel((event) => {
|
|
||||||
setPanels((_) => {
|
|
||||||
const next = [..._];
|
|
||||||
next.splice(
|
|
||||||
next.findIndex((x) => x === event.id),
|
|
||||||
1
|
|
||||||
);
|
|
||||||
|
|
||||||
return next;
|
|
||||||
});
|
|
||||||
addLogLine(`Panel Removed ${event.id}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.onDidAddGroup((event) => {
|
|
||||||
setGroups((_) => [..._, event.id]);
|
|
||||||
addLogLine(`Group Added ${event.id}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.onDidMovePanel((event) => {
|
|
||||||
addLogLine(`Panel Moved ${event.panel.id}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.onDidRemoveGroup((event) => {
|
|
||||||
setGroups((_) => {
|
|
||||||
const next = [..._];
|
|
||||||
next.splice(
|
|
||||||
next.findIndex((x) => x === event.id),
|
|
||||||
1
|
|
||||||
);
|
|
||||||
|
|
||||||
return next;
|
|
||||||
});
|
|
||||||
addLogLine(`Group Removed ${event.id}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.onDidActiveGroupChange((event) => {
|
|
||||||
setActiveGroup(event?.id);
|
|
||||||
addLogLine(`Group Activated ${event?.id}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
const state = localStorage.getItem('dv-demo-state');
|
|
||||||
if (state) {
|
|
||||||
try {
|
|
||||||
event.api.fromJSON(JSON.parse(state));
|
|
||||||
return;
|
|
||||||
} catch {
|
|
||||||
localStorage.removeItem('dv-demo-state');
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultConfig(event.api);
|
|
||||||
};
|
|
||||||
|
|
||||||
const [watermark, setWatermark] = React.useState<boolean>(false);
|
|
||||||
|
|
||||||
const [gapCheck, setGapCheck] = React.useState<boolean>(false);
|
|
||||||
|
|
||||||
const css = React.useMemo(() => {
|
|
||||||
if (!gapCheck) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
'--dv-group-gap-size': '0.5rem',
|
|
||||||
'--demo-border': '5px dashed purple',
|
|
||||||
} as React.CSSProperties;
|
|
||||||
}, [gapCheck]);
|
|
||||||
|
|
||||||
const [showLogs, setShowLogs] = React.useState<boolean>(false);
|
|
||||||
const [debug, setDebug] = React.useState<boolean>(false);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: '100%',
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
flexGrow: 1,
|
|
||||||
padding: '8px',
|
|
||||||
backgroundColor: 'rgba(0,0,50,0.25)',
|
|
||||||
borderRadius: '8px',
|
|
||||||
position: 'relative',
|
|
||||||
...css,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<GridActions
|
|
||||||
api={api}
|
|
||||||
toggleCustomWatermark={() => setWatermark(!watermark)}
|
|
||||||
hasCustomWatermark={watermark}
|
|
||||||
/>
|
|
||||||
{api && (
|
|
||||||
<PanelActions
|
|
||||||
api={api}
|
|
||||||
panels={panels}
|
|
||||||
activePanel={activePanel}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{api && (
|
|
||||||
<GroupActions
|
|
||||||
api={api}
|
|
||||||
groups={groups}
|
|
||||||
activeGroup={activeGroup}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{/* <div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
setGapCheck(!gapCheck);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{gapCheck ? 'Disable Gap Check' : 'Enable Gap Check'}
|
|
||||||
</button>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="action-container"
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'flex-end',
|
|
||||||
alignItems: 'center',
|
|
||||||
padding: '4px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
setDebug(!debug);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="material-symbols-outlined">
|
|
||||||
engineering
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
setShowLogs(!showLogs);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span style={{ paddingRight: '4px' }}>
|
|
||||||
{`${showLogs ? 'Hide' : 'Show'} Events Log`}
|
|
||||||
</span>
|
|
||||||
<span className="material-symbols-outlined">terminal</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flexGrow: 1,
|
|
||||||
height: 0,
|
|
||||||
display: 'flex',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flexGrow: 1,
|
|
||||||
overflow: 'hidden',
|
|
||||||
height: '100%',
|
|
||||||
display: 'flex',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DebugContext.Provider value={debug}>
|
|
||||||
<DockviewReact
|
|
||||||
components={components}
|
|
||||||
defaultTabComponent={headerComponents.default}
|
|
||||||
rightHeaderActionsComponent={RightControls}
|
|
||||||
leftHeaderActionsComponent={LeftControls}
|
|
||||||
prefixHeaderActionsComponent={PrefixHeaderControls}
|
|
||||||
watermarkComponent={
|
|
||||||
watermark ? WatermarkComponent : undefined
|
|
||||||
}
|
|
||||||
onReady={onReady}
|
|
||||||
className={props.theme || 'dockview-theme-abyss'}
|
|
||||||
/>
|
|
||||||
</DebugContext.Provider>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{showLogs && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
width: '400px',
|
|
||||||
backgroundColor: 'black',
|
|
||||||
color: 'white',
|
|
||||||
overflow: 'auto',
|
|
||||||
fontFamily: 'monospace',
|
|
||||||
marginLeft: '10px',
|
|
||||||
flexShrink: 0,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{logLines.map((line, i) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: '30px',
|
|
||||||
overflow: 'hidden',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
fontSize: '13px',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
|
|
||||||
backgroundColor: line.backgroundColor,
|
|
||||||
}}
|
|
||||||
key={i}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
minWidth: '20px',
|
|
||||||
maxWidth: '20px',
|
|
||||||
color: 'gray',
|
|
||||||
borderRight: '1px solid gray',
|
|
||||||
marginRight: '4px',
|
|
||||||
paddingLeft: '4px',
|
|
||||||
height: '100%',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{logLines.length - i}
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
{line.timestamp && (
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: '0.7em',
|
|
||||||
padding: '0px 2px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{line.timestamp
|
|
||||||
.toISOString()
|
|
||||||
.substring(11, 23)}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
<span>{line.text}</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DockviewDemo;
|
|
@ -1,148 +0,0 @@
|
|||||||
import { IDockviewHeaderActionsProps } from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
import { nextId } from './defaultLayout';
|
|
||||||
|
|
||||||
const Icon = (props: {
|
|
||||||
icon: string;
|
|
||||||
title?: string;
|
|
||||||
onClick?: (event: React.MouseEvent) => void;
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<div title={props.title} className="action" onClick={props.onClick}>
|
|
||||||
<span
|
|
||||||
style={{ fontSize: 'inherit' }}
|
|
||||||
className="material-symbols-outlined"
|
|
||||||
>
|
|
||||||
{props.icon}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const groupControlsComponents: Record<string, React.FC> = {
|
|
||||||
panel_1: () => {
|
|
||||||
return <Icon icon="file_download" />;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const RightControls = (props: IDockviewHeaderActionsProps) => {
|
|
||||||
const Component = React.useMemo(() => {
|
|
||||||
if (!props.isGroupActive || !props.activePanel) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return groupControlsComponents[props.activePanel.id];
|
|
||||||
}, [props.isGroupActive, props.activePanel]);
|
|
||||||
|
|
||||||
const [isMaximized, setIsMaximized] = React.useState<boolean>(
|
|
||||||
props.containerApi.hasMaximizedGroup()
|
|
||||||
);
|
|
||||||
|
|
||||||
const [isPopout, setIsPopout] = React.useState<boolean>(
|
|
||||||
props.api.location.type === 'popout'
|
|
||||||
);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const disposable = props.containerApi.onDidMaximizedGroupChange(() => {
|
|
||||||
setIsMaximized(props.containerApi.hasMaximizedGroup());
|
|
||||||
});
|
|
||||||
|
|
||||||
const disposable2 = props.api.onDidLocationChange(() => {
|
|
||||||
setIsPopout(props.api.location.type === 'popout');
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
disposable.dispose();
|
|
||||||
disposable2.dispose();
|
|
||||||
};
|
|
||||||
}, [props.containerApi]);
|
|
||||||
|
|
||||||
const onClick = () => {
|
|
||||||
if (props.containerApi.hasMaximizedGroup()) {
|
|
||||||
props.containerApi.exitMaximizedGroup();
|
|
||||||
} else {
|
|
||||||
props.activePanel?.api.maximize();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onClick2 = () => {
|
|
||||||
if (props.api.location.type !== 'popout') {
|
|
||||||
props.containerApi.addPopoutGroup(props.group);
|
|
||||||
} else {
|
|
||||||
props.api.moveTo({ position: 'right' });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="group-control"
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
padding: '0px 8px',
|
|
||||||
height: '100%',
|
|
||||||
color: 'var(--dv-activegroup-visiblepanel-tab-color)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{props.isGroupActive && <Icon icon="star" />}
|
|
||||||
{Component && <Component />}
|
|
||||||
<Icon
|
|
||||||
title={isPopout ? 'Close Window' : 'Open In New Window'}
|
|
||||||
icon={isPopout ? 'close_fullscreen' : 'open_in_new'}
|
|
||||||
onClick={onClick2}
|
|
||||||
/>
|
|
||||||
{!isPopout && (
|
|
||||||
<Icon
|
|
||||||
title={isMaximized ? 'Minimize View' : 'Maximize View'}
|
|
||||||
icon={isMaximized ? 'collapse_content' : 'expand_content'}
|
|
||||||
onClick={onClick}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LeftControls = (props: IDockviewHeaderActionsProps) => {
|
|
||||||
const onClick = () => {
|
|
||||||
props.containerApi.addPanel({
|
|
||||||
id: `id_${Date.now().toString()}`,
|
|
||||||
component: 'default',
|
|
||||||
title: `Tab ${nextId()}`,
|
|
||||||
position: {
|
|
||||||
referenceGroup: props.group,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="group-control"
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
padding: '0px 8px',
|
|
||||||
height: '100%',
|
|
||||||
color: 'var(--dv-activegroup-visiblepanel-tab-color)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Icon onClick={onClick} icon="add" />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const PrefixHeaderControls = (props: IDockviewHeaderActionsProps) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="group-control"
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
padding: '0px 8px',
|
|
||||||
height: '100%',
|
|
||||||
color: 'var(--dv-activegroup-visiblepanel-tab-color)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Icon icon="Menu" />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,164 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewGroupLocation,
|
|
||||||
DockviewPanelApi,
|
|
||||||
DockviewPanelRenderer,
|
|
||||||
} from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
export interface PanelApiMetadata {
|
|
||||||
isActive: {
|
|
||||||
value: boolean;
|
|
||||||
count: number;
|
|
||||||
};
|
|
||||||
isVisible: {
|
|
||||||
value: boolean;
|
|
||||||
count: number;
|
|
||||||
};
|
|
||||||
renderer: {
|
|
||||||
value: DockviewPanelRenderer;
|
|
||||||
count: number;
|
|
||||||
};
|
|
||||||
isGroupActive: {
|
|
||||||
value: boolean;
|
|
||||||
count: number;
|
|
||||||
};
|
|
||||||
groupChanged: {
|
|
||||||
count: number;
|
|
||||||
};
|
|
||||||
location: {
|
|
||||||
value: DockviewGroupLocation;
|
|
||||||
count: number;
|
|
||||||
};
|
|
||||||
didFocus: {
|
|
||||||
count: number;
|
|
||||||
};
|
|
||||||
dimensions: {
|
|
||||||
count: number;
|
|
||||||
value: { height: number; width: number };
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Table = (props: { data: PanelApiMetadata }) => {
|
|
||||||
return (
|
|
||||||
<div className="data-table">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>{'Key'}</th>
|
|
||||||
<th>{'Count'}</th>
|
|
||||||
<th>{'Value'}</th>
|
|
||||||
</tr>
|
|
||||||
{Object.entries(props.data).map(([key, value]) => {
|
|
||||||
return (
|
|
||||||
<tr key={key}>
|
|
||||||
<th>{key}</th>
|
|
||||||
<th>{value.count}</th>
|
|
||||||
<th>{JSON.stringify(value.value, null, 4)}</th>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export function usePanelApiMetadata(api: DockviewPanelApi): PanelApiMetadata {
|
|
||||||
const [state, setState] = React.useState<PanelApiMetadata>({
|
|
||||||
isActive: { value: api.isActive, count: 0 },
|
|
||||||
isVisible: { value: api.isVisible, count: 0 },
|
|
||||||
renderer: { value: api.renderer, count: 0 },
|
|
||||||
isGroupActive: { value: api.isGroupActive, count: 0 },
|
|
||||||
groupChanged: { count: 0 },
|
|
||||||
location: { value: api.location, count: 0 },
|
|
||||||
didFocus: { count: 0 },
|
|
||||||
dimensions: {
|
|
||||||
count: 0,
|
|
||||||
value: { height: api.height, width: api.width },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const d1 = api.onDidActiveChange((event) => {
|
|
||||||
setState((_) => ({
|
|
||||||
..._,
|
|
||||||
isActive: {
|
|
||||||
value: event.isActive,
|
|
||||||
count: _.isActive.count + 1,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
const d2 = api.onDidActiveGroupChange((event) => {
|
|
||||||
setState((_) => ({
|
|
||||||
..._,
|
|
||||||
isGroupActive: {
|
|
||||||
value: event.isActive,
|
|
||||||
count: _.isGroupActive.count + 1,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
const d3 = api.onDidDimensionsChange((event) => {
|
|
||||||
setState((_) => ({
|
|
||||||
..._,
|
|
||||||
dimensions: {
|
|
||||||
count: _.dimensions.count + 1,
|
|
||||||
value: { height: event.height, width: event.width },
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
const d4 = api.onDidFocusChange((event) => {
|
|
||||||
setState((_) => ({
|
|
||||||
..._,
|
|
||||||
didFocus: {
|
|
||||||
count: _.didFocus.count + 1,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
const d5 = api.onDidGroupChange((event) => {
|
|
||||||
setState((_) => ({
|
|
||||||
..._,
|
|
||||||
groupChanged: {
|
|
||||||
count: _.groupChanged.count + 1,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
const d7 = api.onDidLocationChange((event) => {
|
|
||||||
setState((_) => ({
|
|
||||||
..._,
|
|
||||||
location: {
|
|
||||||
value: event.location,
|
|
||||||
count: _.location.count + 1,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
const d8 = api.onDidRendererChange((event) => {
|
|
||||||
setState((_) => ({
|
|
||||||
..._,
|
|
||||||
renderer: {
|
|
||||||
value: event.renderer,
|
|
||||||
count: _.renderer.count + 1,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
const d9 = api.onDidVisibilityChange((event) => {
|
|
||||||
setState((_) => ({
|
|
||||||
..._,
|
|
||||||
isVisible: {
|
|
||||||
value: event.isVisible,
|
|
||||||
count: _.isVisible.count + 1,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
d1.dispose();
|
|
||||||
d2.dispose();
|
|
||||||
d3.dispose();
|
|
||||||
d4.dispose();
|
|
||||||
d5.dispose();
|
|
||||||
d7.dispose();
|
|
||||||
d8.dispose();
|
|
||||||
d9.dispose();
|
|
||||||
};
|
|
||||||
}, [api]);
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
import { DockviewApi } from 'dockview';
|
|
||||||
|
|
||||||
export const nextId = (() => {
|
|
||||||
let counter = 0;
|
|
||||||
|
|
||||||
return () => counter++;
|
|
||||||
})();
|
|
||||||
|
|
||||||
export function defaultConfig(api: DockviewApi) {
|
|
||||||
const panel1 = api.addPanel({
|
|
||||||
id: 'panel_1',
|
|
||||||
component: 'default',
|
|
||||||
renderer: 'always',
|
|
||||||
title: 'Panel 1',
|
|
||||||
});
|
|
||||||
|
|
||||||
api.addPanel({
|
|
||||||
id: 'panel_2',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 2',
|
|
||||||
position: { referencePanel: panel1 },
|
|
||||||
});
|
|
||||||
|
|
||||||
api.addPanel({
|
|
||||||
id: 'panel_3',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 3',
|
|
||||||
position: { referencePanel: panel1 },
|
|
||||||
});
|
|
||||||
|
|
||||||
const panel4 = api.addPanel({
|
|
||||||
id: 'panel_4',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 4',
|
|
||||||
position: { referencePanel: panel1, direction: 'right' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const panel5 = api.addPanel({
|
|
||||||
id: 'panel_5',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 5',
|
|
||||||
position: { referencePanel: panel4 },
|
|
||||||
});
|
|
||||||
|
|
||||||
const panel6 = api.addPanel({
|
|
||||||
id: 'panel_6',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 6',
|
|
||||||
position: { referencePanel: panel5, direction: 'below' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const panel7 = api.addPanel({
|
|
||||||
id: 'panel_7',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 7',
|
|
||||||
position: { referencePanel: panel6, direction: 'left' },
|
|
||||||
});
|
|
||||||
|
|
||||||
api.addPanel({
|
|
||||||
id: 'panel8',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 8',
|
|
||||||
position: { referencePanel: panel7, direction: 'below' },
|
|
||||||
});
|
|
||||||
|
|
||||||
panel1.api.setActive();
|
|
||||||
}
|
|
@ -1,216 +0,0 @@
|
|||||||
import { DockviewApi } from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
import { defaultConfig, nextId } from './defaultLayout';
|
|
||||||
|
|
||||||
import { createRoot, Root } from 'react-dom/client';
|
|
||||||
import { PanelBuilder } from './panelBuilder';
|
|
||||||
|
|
||||||
let mount = document.querySelector('.popover-anchor') as HTMLElement | null;
|
|
||||||
|
|
||||||
if (!mount) {
|
|
||||||
mount = document.createElement('div');
|
|
||||||
mount.className = 'popover-anchor';
|
|
||||||
document.body.insertBefore(mount, document.body.firstChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
const PopoverComponent = (props: {
|
|
||||||
close: () => void;
|
|
||||||
component: React.FC<{ close: () => void }>;
|
|
||||||
}) => {
|
|
||||||
const ref = React.useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const handler = (ev: MouseEvent) => {
|
|
||||||
let target = ev.target as HTMLElement;
|
|
||||||
|
|
||||||
while (target.parentElement) {
|
|
||||||
if (target === ref.current) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
target = target.parentElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
props.close();
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener('mousedown', handler);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
window.removeEventListener('mousedown', handler);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
position: 'absolute',
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
zIndex: 9999,
|
|
||||||
height: '100%',
|
|
||||||
width: '100%',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
ref={ref}
|
|
||||||
style={{
|
|
||||||
position: 'absolute',
|
|
||||||
top: '50%',
|
|
||||||
left: '50%',
|
|
||||||
transform: 'translate(-50%,-50%)',
|
|
||||||
backgroundColor: 'black',
|
|
||||||
color: 'white',
|
|
||||||
padding: 10,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<props.component close={props.close} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
function usePopover() {
|
|
||||||
return {
|
|
||||||
open: (Component: React.FC<{ close: () => void }>) => {
|
|
||||||
const el = document.createElement('div');
|
|
||||||
mount!.appendChild(el);
|
|
||||||
const root = createRoot(el);
|
|
||||||
|
|
||||||
root.render(
|
|
||||||
<PopoverComponent
|
|
||||||
component={Component}
|
|
||||||
close={() => {
|
|
||||||
root.unmount();
|
|
||||||
el.remove();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export const GridActions = (props: {
|
|
||||||
api?: DockviewApi;
|
|
||||||
hasCustomWatermark: boolean;
|
|
||||||
toggleCustomWatermark: () => void;
|
|
||||||
}) => {
|
|
||||||
const onClear = () => {
|
|
||||||
props.api?.clear();
|
|
||||||
};
|
|
||||||
|
|
||||||
const onLoad = () => {
|
|
||||||
const state = localStorage.getItem('dv-demo-state');
|
|
||||||
if (state) {
|
|
||||||
try {
|
|
||||||
props.api?.fromJSON(JSON.parse(state));
|
|
||||||
} catch (err) {
|
|
||||||
console.error('failed to load state', err);
|
|
||||||
localStorage.removeItem('dv-demo-state');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSave = () => {
|
|
||||||
if (props.api) {
|
|
||||||
console.log(props.api.toJSON());
|
|
||||||
localStorage.setItem(
|
|
||||||
'dv-demo-state',
|
|
||||||
JSON.stringify(props.api.toJSON())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onReset = () => {
|
|
||||||
if (props.api) {
|
|
||||||
try {
|
|
||||||
props.api.clear();
|
|
||||||
defaultConfig(props.api);
|
|
||||||
} catch (err) {
|
|
||||||
localStorage.removeItem('dv-demo-state');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const popover = usePopover();
|
|
||||||
|
|
||||||
const onAddPanel = (options?: { advanced: boolean }) => {
|
|
||||||
if (options?.advanced) {
|
|
||||||
popover.open(({ close }) => {
|
|
||||||
return <PanelBuilder api={props.api!} done={close} />;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
props.api?.addPanel({
|
|
||||||
id: `id_${Date.now().toString()}`,
|
|
||||||
component: 'default',
|
|
||||||
title: `Tab ${nextId()}`,
|
|
||||||
renderer: 'always',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onAddGroup = () => {
|
|
||||||
props.api?.addGroup();
|
|
||||||
};
|
|
||||||
|
|
||||||
const [gap, setGap] = React.useState(0);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
props.api?.setGap(gap);
|
|
||||||
}, [gap, props.api]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="action-container">
|
|
||||||
<div className="button-group">
|
|
||||||
<button className="text-button" onClick={() => onAddPanel()}>
|
|
||||||
Add Panel
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="demo-icon-button"
|
|
||||||
onClick={() => onAddPanel({ advanced: true })}
|
|
||||||
>
|
|
||||||
<span className="material-symbols-outlined">tune</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<button className="text-button" onClick={onAddGroup}>
|
|
||||||
Add Group
|
|
||||||
</button>
|
|
||||||
<span className="button-action">
|
|
||||||
<button
|
|
||||||
className={
|
|
||||||
props.hasCustomWatermark
|
|
||||||
? 'demo-button selected'
|
|
||||||
: 'demo-button'
|
|
||||||
}
|
|
||||||
onClick={props.toggleCustomWatermark}
|
|
||||||
>
|
|
||||||
Use Custom Watermark
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
<button className="text-button" onClick={onClear}>
|
|
||||||
Clear
|
|
||||||
</button>
|
|
||||||
<button className="text-button" onClick={onLoad}>
|
|
||||||
Load
|
|
||||||
</button>
|
|
||||||
<button className="text-button" onClick={onSave}>
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
<button className="text-button" onClick={onReset}>
|
|
||||||
Reset
|
|
||||||
</button>
|
|
||||||
<span style={{ flexGrow: 1 }} />
|
|
||||||
<div style={{ display: 'flex' }}>
|
|
||||||
<span style={{ paddingRight: '4px' }}>Group Gap</span>
|
|
||||||
<input
|
|
||||||
style={{ width: 40 }}
|
|
||||||
type="number"
|
|
||||||
min={0}
|
|
||||||
max={99}
|
|
||||||
step={1}
|
|
||||||
value={gap}
|
|
||||||
onChange={(event) => setGap(Number(event.target.value))}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,189 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewApi,
|
|
||||||
DockviewGroupLocation,
|
|
||||||
DockviewGroupPanel,
|
|
||||||
} from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
const GroupAction = (props: {
|
|
||||||
groupId: string;
|
|
||||||
groups: string[];
|
|
||||||
api: DockviewApi;
|
|
||||||
activeGroup?: string;
|
|
||||||
}) => {
|
|
||||||
const onClick = () => {
|
|
||||||
props.api?.getGroup(props.groupId)?.focus();
|
|
||||||
};
|
|
||||||
|
|
||||||
const isActive = props.activeGroup === props.groupId;
|
|
||||||
|
|
||||||
const [group, setGroup] = React.useState<DockviewGroupPanel | undefined>(
|
|
||||||
undefined
|
|
||||||
);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const disposable = props.api.onDidLayoutFromJSON(() => {
|
|
||||||
setGroup(props.api.getGroup(props.groupId));
|
|
||||||
});
|
|
||||||
|
|
||||||
setGroup(props.api.getGroup(props.groupId));
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
disposable.dispose();
|
|
||||||
};
|
|
||||||
}, [props.api, props.groupId]);
|
|
||||||
|
|
||||||
const [location, setLocation] =
|
|
||||||
React.useState<DockviewGroupLocation | null>(null);
|
|
||||||
const [isMaximized, setIsMaximized] = React.useState<boolean>(false);
|
|
||||||
const [isVisible, setIsVisible] = React.useState<boolean>(true);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (!group) {
|
|
||||||
setLocation(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const disposable = group.api.onDidLocationChange((event) => {
|
|
||||||
setLocation(event.location);
|
|
||||||
});
|
|
||||||
|
|
||||||
const disposable2 = props.api.onDidMaximizedGroupChange(() => {
|
|
||||||
setIsMaximized(group.api.isMaximized());
|
|
||||||
});
|
|
||||||
|
|
||||||
const disposable3 = group.api.onDidVisibilityChange(() => {
|
|
||||||
setIsVisible(group.api.isVisible);
|
|
||||||
});
|
|
||||||
|
|
||||||
setLocation(group.api.location);
|
|
||||||
setIsMaximized(group.api.isMaximized());
|
|
||||||
setIsVisible(group.api.isVisible);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
disposable.dispose();
|
|
||||||
disposable2.dispose();
|
|
||||||
disposable3.dispose();
|
|
||||||
};
|
|
||||||
}, [group]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="button-action">
|
|
||||||
<div style={{ display: 'flex' }}>
|
|
||||||
<button
|
|
||||||
onClick={onClick}
|
|
||||||
className={
|
|
||||||
isActive ? 'demo-button selected' : 'demo-button'
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{props.groupId}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div style={{ display: 'flex' }}>
|
|
||||||
<button
|
|
||||||
className={
|
|
||||||
location?.type === 'floating'
|
|
||||||
? 'demo-icon-button selected'
|
|
||||||
: 'demo-icon-button'
|
|
||||||
}
|
|
||||||
onClick={() => {
|
|
||||||
if (group) {
|
|
||||||
|
|
||||||
props.api.addFloatingGroup(group, {
|
|
||||||
width: 400,
|
|
||||||
height: 300,
|
|
||||||
x: 50,
|
|
||||||
y: 50,
|
|
||||||
position: {
|
|
||||||
bottom: 50,
|
|
||||||
right: 50,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="material-symbols-outlined">ad_group</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className={
|
|
||||||
location?.type === 'popout'
|
|
||||||
? 'demo-icon-button selected'
|
|
||||||
: 'demo-icon-button'
|
|
||||||
}
|
|
||||||
onClick={() => {
|
|
||||||
if (group) {
|
|
||||||
props.api.addPopoutGroup(group);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="material-symbols-outlined">
|
|
||||||
open_in_new
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className={
|
|
||||||
isMaximized
|
|
||||||
? 'demo-icon-button selected'
|
|
||||||
: 'demo-icon-button'
|
|
||||||
}
|
|
||||||
onClick={() => {
|
|
||||||
if (group) {
|
|
||||||
if (group.api.isMaximized()) {
|
|
||||||
group.api.exitMaximized();
|
|
||||||
} else {
|
|
||||||
group.api.maximize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="material-symbols-outlined">
|
|
||||||
fullscreen
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="demo-icon-button"
|
|
||||||
onClick={() => {
|
|
||||||
console.log(group);
|
|
||||||
if (group) {
|
|
||||||
if (group.api.isVisible) {
|
|
||||||
group.api.setVisible(false);
|
|
||||||
} else {
|
|
||||||
group.api.setVisible(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="material-symbols-outlined">
|
|
||||||
{isVisible ? 'visibility' : 'visibility_off'}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="demo-icon-button"
|
|
||||||
onClick={() => {
|
|
||||||
const panel = props.api?.getGroup(props.groupId);
|
|
||||||
panel?.api.close();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="material-symbols-outlined">close</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const GroupActions = (props: {
|
|
||||||
groups: string[];
|
|
||||||
api: DockviewApi;
|
|
||||||
activeGroup?: string;
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<div className="action-container">
|
|
||||||
{props.groups.map((groupId) => {
|
|
||||||
return (
|
|
||||||
<GroupAction key={groupId} {...props} groupId={groupId} />
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,20 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,138 +0,0 @@
|
|||||||
import { DockviewApi, IDockviewPanel } from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
const PanelAction = (props: {
|
|
||||||
panels: string[];
|
|
||||||
api: DockviewApi;
|
|
||||||
activePanel?: string;
|
|
||||||
panelId: string;
|
|
||||||
}) => {
|
|
||||||
const onClick = () => {
|
|
||||||
props.api.getPanel(props.panelId)?.focus();
|
|
||||||
};
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const panel = props.api.getPanel(props.panelId);
|
|
||||||
if (panel) {
|
|
||||||
const disposable = panel.api.onDidVisibilityChange((event) => {
|
|
||||||
setVisible(event.isVisible);
|
|
||||||
});
|
|
||||||
setVisible(panel.api.isVisible);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
disposable.dispose();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}, [props.api, props.panelId]);
|
|
||||||
|
|
||||||
const [panel, setPanel] = React.useState<IDockviewPanel | undefined>(
|
|
||||||
undefined
|
|
||||||
);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const list = [
|
|
||||||
props.api.onDidLayoutFromJSON(() => {
|
|
||||||
setPanel(props.api.getPanel(props.panelId));
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
|
|
||||||
if (panel) {
|
|
||||||
const disposable = panel.api.onDidVisibilityChange((event) => {
|
|
||||||
setVisible(event.isVisible);
|
|
||||||
});
|
|
||||||
setVisible(panel.api.isVisible);
|
|
||||||
|
|
||||||
list.push(disposable);
|
|
||||||
}
|
|
||||||
|
|
||||||
setPanel(props.api.getPanel(props.panelId));
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
list.forEach((l) => l.dispose());
|
|
||||||
};
|
|
||||||
}, [props.api, props.panelId]);
|
|
||||||
|
|
||||||
const [visible, setVisible] = React.useState<boolean>(true);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="button-action">
|
|
||||||
<div style={{ display: 'flex' }}>
|
|
||||||
<button
|
|
||||||
className={
|
|
||||||
props.activePanel === props.panelId
|
|
||||||
? 'demo-button selected'
|
|
||||||
: 'demo-button'
|
|
||||||
}
|
|
||||||
onClick={onClick}
|
|
||||||
>
|
|
||||||
{props.panelId}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div style={{ display: 'flex' }}>
|
|
||||||
<button
|
|
||||||
className="demo-icon-button"
|
|
||||||
onClick={() => {
|
|
||||||
const panel = props.api.getPanel(props.panelId);
|
|
||||||
if (panel) {
|
|
||||||
props.api.addFloatingGroup(panel, {
|
|
||||||
position: {
|
|
||||||
width: 400,
|
|
||||||
height: 300,
|
|
||||||
bottom: 50,
|
|
||||||
right: 50,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="material-symbols-outlined">ad_group</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="demo-icon-button"
|
|
||||||
onClick={() => {
|
|
||||||
const panel = props.api.getPanel(props.panelId);
|
|
||||||
if (panel) {
|
|
||||||
props.api.addPopoutGroup(panel);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="material-symbols-outlined">
|
|
||||||
open_in_new
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="demo-icon-button"
|
|
||||||
onClick={() => {
|
|
||||||
const panel = props.api.getPanel(props.panelId);
|
|
||||||
panel?.api.close();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="material-symbols-outlined">close</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
title="Panel visiblity cannot be edited manually."
|
|
||||||
disabled={true}
|
|
||||||
className="demo-icon-button"
|
|
||||||
>
|
|
||||||
<span className="material-symbols-outlined">
|
|
||||||
{visible ? 'visibility' : 'visibility_off'}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const PanelActions = (props: {
|
|
||||||
panels: string[];
|
|
||||||
api: DockviewApi;
|
|
||||||
activePanel?: string;
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<div className="action-container">
|
|
||||||
{props.panels.map((id) => {
|
|
||||||
return <PanelAction key={id} {...props} panelId={id} />;
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,115 +0,0 @@
|
|||||||
import { DockviewApi } from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
import { nextId } from './defaultLayout';
|
|
||||||
|
|
||||||
export const PanelBuilder = (props: { api: DockviewApi; done: () => void }) => {
|
|
||||||
const [parameters, setParameters] = React.useState<{
|
|
||||||
initialWidth?: number;
|
|
||||||
initialHeight?: number;
|
|
||||||
maximumHeight?: number;
|
|
||||||
maximumWidth?: number;
|
|
||||||
minimumHeight?: number;
|
|
||||||
minimumWidth?: number;
|
|
||||||
}>({});
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'grid',
|
|
||||||
gridTemplateColumns: '1fr 1fr',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div>{'Initial Width'}</div>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
value={parameters.initialWidth}
|
|
||||||
onChange={(event) =>
|
|
||||||
setParameters((_) => ({
|
|
||||||
..._,
|
|
||||||
initialWidth: Number(event.target.value),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<div>{'Initial Height'}</div>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
value={parameters.initialHeight}
|
|
||||||
onChange={(event) =>
|
|
||||||
setParameters((_) => ({
|
|
||||||
..._,
|
|
||||||
initialHeight: Number(event.target.value),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<div>{'Maximum Width'}</div>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
value={parameters.maximumWidth}
|
|
||||||
onChange={(event) =>
|
|
||||||
setParameters((_) => ({
|
|
||||||
..._,
|
|
||||||
maximumWidth: Number(event.target.value),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<div>{'Maximum Height'}</div>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
value={parameters.maximumHeight}
|
|
||||||
onChange={(event) =>
|
|
||||||
setParameters((_) => ({
|
|
||||||
..._,
|
|
||||||
maximumHeight: Number(event.target.value),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<div>{'Minimum Width'}</div>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
value={parameters.minimumWidth}
|
|
||||||
onChange={(event) =>
|
|
||||||
setParameters((_) => ({
|
|
||||||
..._,
|
|
||||||
minimumWidth: Number(event.target.value),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<div>{'Minimum Height'}</div>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
value={parameters.minimumHeight}
|
|
||||||
onChange={(event) =>
|
|
||||||
setParameters((_) => ({
|
|
||||||
..._,
|
|
||||||
minimumHeight: Number(event.target.value),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
props.done();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
props.api?.addPanel({
|
|
||||||
id: `id_${Date.now().toString()}`,
|
|
||||||
component: 'default',
|
|
||||||
title: `Tab ${nextId()}`,
|
|
||||||
renderer: 'always',
|
|
||||||
...parameters,
|
|
||||||
});
|
|
||||||
|
|
||||||
props.done();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Go
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "dockview.dnd-events",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.tsx",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview": "*",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/react": "^18.0.28",
|
|
||||||
"@types/react-dom": "^18.0.11",
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,142 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewApi,
|
|
||||||
DockviewReact,
|
|
||||||
DockviewReadyEvent,
|
|
||||||
IDockviewPanelProps,
|
|
||||||
} from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
const Default = (props: IDockviewPanelProps) => {
|
|
||||||
return (
|
|
||||||
<div style={{ height: '100%' }}>
|
|
||||||
<div>{props.api.title}</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
default: Default,
|
|
||||||
};
|
|
||||||
|
|
||||||
const Component = (props: { theme?: string }) => {
|
|
||||||
const [disablePanelDrag, setDisablePanelDrag] =
|
|
||||||
React.useState<boolean>(false);
|
|
||||||
const [disableGroupDrag, setDisableGroupDrag] =
|
|
||||||
React.useState<boolean>(false);
|
|
||||||
const [disableOverlay, setDisableOverlay] = React.useState<boolean>(false);
|
|
||||||
|
|
||||||
const [api, setApi] = React.useState<DockviewApi>();
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (!api) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const disposables = [
|
|
||||||
api.onWillDragPanel((e) => {
|
|
||||||
if (!disablePanelDrag) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
e.nativeEvent.preventDefault();
|
|
||||||
}),
|
|
||||||
|
|
||||||
api.onWillDragGroup((e) => {
|
|
||||||
if (!disableGroupDrag) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
e.nativeEvent.preventDefault();
|
|
||||||
}),
|
|
||||||
api.onWillShowOverlay((e) => {
|
|
||||||
console.log(e);
|
|
||||||
|
|
||||||
if (!disableOverlay) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
}),
|
|
||||||
|
|
||||||
api.onWillDrop((e) => {
|
|
||||||
//
|
|
||||||
}),
|
|
||||||
|
|
||||||
api.onDidDrop((e) => {
|
|
||||||
//
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
disposables.forEach((disposable) => {
|
|
||||||
disposable.dispose();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}, [api, disablePanelDrag, disableGroupDrag, disableOverlay]);
|
|
||||||
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
|
||||||
setApi(event.api);
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_1',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_2',
|
|
||||||
component: 'default',
|
|
||||||
position: {
|
|
||||||
direction: 'right',
|
|
||||||
referencePanel: 'panel_1',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_3',
|
|
||||||
component: 'default',
|
|
||||||
position: {
|
|
||||||
direction: 'below',
|
|
||||||
referencePanel: 'panel_1',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_4',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_5',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{ display: 'flex', flexDirection: 'column', height: '100%' }}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => setDisablePanelDrag(!disablePanelDrag)}
|
|
||||||
>{`Panel Drag: ${
|
|
||||||
disablePanelDrag ? 'disabled' : 'enabled'
|
|
||||||
}`}</button>
|
|
||||||
<button
|
|
||||||
onClick={() => setDisableGroupDrag(!disableGroupDrag)}
|
|
||||||
>{`Group Drag: ${
|
|
||||||
disableGroupDrag ? 'disabled' : 'enabled'
|
|
||||||
}`}</button>
|
|
||||||
<button
|
|
||||||
onClick={() => setDisableOverlay(!disableOverlay)}
|
|
||||||
>{`Overlay: ${
|
|
||||||
disableOverlay ? 'disabled' : 'enabled'
|
|
||||||
}`}</button>
|
|
||||||
</div>
|
|
||||||
<div style={{ flexGrow: 1 }}>
|
|
||||||
<DockviewReact
|
|
||||||
className={`${props.theme || 'dockview-theme-abyss'}`}
|
|
||||||
onReady={onReady}
|
|
||||||
components={components}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Component;
|
|
@ -1,20 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "dockview.dnd-external",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.tsx",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview": "*",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/react": "^18.0.28",
|
|
||||||
"@types/react-dom": "^18.0.11",
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,192 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewApi,
|
|
||||||
DockviewDndOverlayEvent,
|
|
||||||
DockviewDidDropEvent,
|
|
||||||
DockviewReact,
|
|
||||||
DockviewReadyEvent,
|
|
||||||
IDockviewPanelProps,
|
|
||||||
positionToDirection,
|
|
||||||
} from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
default: (props: IDockviewPanelProps<{ title: string }>) => {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: '20px' }}>
|
|
||||||
<div>{props.params.title}</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const DraggableElement = () => (
|
|
||||||
<span
|
|
||||||
tabIndex={-1}
|
|
||||||
onDragStart={(event) => {
|
|
||||||
if (event.dataTransfer) {
|
|
||||||
event.dataTransfer.effectAllowed = 'move';
|
|
||||||
|
|
||||||
event.dataTransfer.setData('text/plain', 'nothing');
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
backgroundColor: 'orange',
|
|
||||||
padding: '0px 8px',
|
|
||||||
borderRadius: '4px',
|
|
||||||
width: '100px',
|
|
||||||
cursor: 'pointer',
|
|
||||||
}}
|
|
||||||
draggable={true}
|
|
||||||
>
|
|
||||||
Drag me into the dock
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
|
|
||||||
const DndDockview = (props: { renderVisibleOnly: boolean; theme?: string }) => {
|
|
||||||
const [api, setApi] = React.useState<DockviewApi>();
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (!api) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const panelDragDisposable = api.onWillDragPanel((event) => {
|
|
||||||
const dataTransfer = event.nativeEvent.dataTransfer;
|
|
||||||
|
|
||||||
if (dataTransfer) {
|
|
||||||
dataTransfer.setData(
|
|
||||||
'text/plain',
|
|
||||||
'Some custom panel data transfer data'
|
|
||||||
);
|
|
||||||
dataTransfer.setData(
|
|
||||||
'text/json',
|
|
||||||
'{text: "Some custom panel data transfer data"}'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const groupDragDisposable = api.onWillDragGroup((event) => {
|
|
||||||
const dataTransfer = event.nativeEvent.dataTransfer;
|
|
||||||
|
|
||||||
if (dataTransfer) {
|
|
||||||
dataTransfer.setData(
|
|
||||||
'text/plain',
|
|
||||||
'Some custom group data transfer data'
|
|
||||||
);
|
|
||||||
dataTransfer.setData(
|
|
||||||
'text/json',
|
|
||||||
'{text: "Some custom group data transfer data"}'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
panelDragDisposable.dispose();
|
|
||||||
groupDragDisposable.dispose();
|
|
||||||
};
|
|
||||||
}, [api]);
|
|
||||||
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
|
||||||
setApi(event.api);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDidDrop = (event: DockviewDidDropEvent) => {
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'test',
|
|
||||||
component: 'default',
|
|
||||||
position: {
|
|
||||||
direction: positionToDirection(event.position),
|
|
||||||
referenceGroup: event.group || undefined,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const showDndOverlay = (event: DockviewDndOverlayEvent) => {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDrop = (event: React.DragEvent) => {
|
|
||||||
const dataTransfer = event.dataTransfer;
|
|
||||||
|
|
||||||
let text = 'The following dataTransfer data was found:\n';
|
|
||||||
|
|
||||||
for (let i = 0; i < dataTransfer.items.length; i++) {
|
|
||||||
const item = dataTransfer.items[i];
|
|
||||||
const value = dataTransfer.getData(item.type);
|
|
||||||
text += `type=${item.type},data=${value}\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
alert(text);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
height: '100%',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div style={{ margin: '2px 0px' }}>
|
|
||||||
<DraggableElement />
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
padding: '0px 4px',
|
|
||||||
backgroundColor: 'black',
|
|
||||||
borderRadius: '2px',
|
|
||||||
color: 'white',
|
|
||||||
}}
|
|
||||||
onDrop={onDrop}
|
|
||||||
>
|
|
||||||
Drop a tab or group here to inspect the attached metadata
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<DockviewReact
|
|
||||||
components={components}
|
|
||||||
onReady={onReady}
|
|
||||||
className={`${props.theme || 'dockview-theme-abyss'}`}
|
|
||||||
onDidDrop={onDidDrop}
|
|
||||||
showDndOverlay={showDndOverlay}
|
|
||||||
rootOverlayModel={{
|
|
||||||
size: { value: 100, type: 'pixels' },
|
|
||||||
activationSize: { value: 5, type: 'percentage' },
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DndDockview;
|
|
@ -1,20 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "dockview.floating-groups",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.tsx",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview": "*",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/react": "^18.0.28",
|
|
||||||
"@types/react-dom": "^18.0.11",
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,301 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewApi,
|
|
||||||
DockviewGroupPanel,
|
|
||||||
DockviewReact,
|
|
||||||
DockviewReadyEvent,
|
|
||||||
IDockviewHeaderActionsProps,
|
|
||||||
IDockviewPanelProps,
|
|
||||||
SerializedDockview,
|
|
||||||
} from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
import { Icon } from './utils';
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
default: (props: IDockviewPanelProps<{ title: string }>) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: '100%',
|
|
||||||
padding: '20px',
|
|
||||||
background: 'var(--dv-group-view-background-color)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{props.params.title}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const counter = (() => {
|
|
||||||
let i = 0;
|
|
||||||
|
|
||||||
return {
|
|
||||||
next: () => ++i,
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
function loadDefaultLayout(api: DockviewApi) {
|
|
||||||
api.addPanel({
|
|
||||||
id: 'panel_1',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
api.addPanel({
|
|
||||||
id: 'panel_2',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
api.addPanel({
|
|
||||||
id: 'panel_3',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
const panel4 = api.addPanel({
|
|
||||||
id: 'panel_4',
|
|
||||||
component: 'default',
|
|
||||||
floating: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
api.addPanel({
|
|
||||||
id: 'panel_5',
|
|
||||||
component: 'default',
|
|
||||||
floating: false,
|
|
||||||
position: { referencePanel: panel4 },
|
|
||||||
});
|
|
||||||
|
|
||||||
api.addPanel({
|
|
||||||
id: 'panel_6',
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let panelCount = 0;
|
|
||||||
|
|
||||||
function addPanel(api: DockviewApi) {
|
|
||||||
api.addPanel({
|
|
||||||
id: (++panelCount).toString(),
|
|
||||||
title: `Tab ${panelCount}`,
|
|
||||||
component: 'default',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function addFloatingPanel2(api: DockviewApi) {
|
|
||||||
api.addPanel({
|
|
||||||
id: (++panelCount).toString(),
|
|
||||||
title: `Tab ${panelCount}`,
|
|
||||||
component: 'default',
|
|
||||||
floating: { width: 250, height: 150, left: 50, top: 50 },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function safeParse<T>(value: any): T | null {
|
|
||||||
try {
|
|
||||||
return JSON.parse(value) as T;
|
|
||||||
} catch (err) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const useLocalStorage = <T,>(
|
|
||||||
key: string
|
|
||||||
): [T | null, (setter: T | null) => void] => {
|
|
||||||
const [state, setState] = React.useState<T | null>(
|
|
||||||
safeParse(localStorage.getItem(key))
|
|
||||||
);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const _state = localStorage.getItem('key');
|
|
||||||
try {
|
|
||||||
if (_state !== null) {
|
|
||||||
setState(JSON.parse(_state));
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}, [key]);
|
|
||||||
|
|
||||||
return [
|
|
||||||
state,
|
|
||||||
(_state: T | null) => {
|
|
||||||
if (_state === null) {
|
|
||||||
localStorage.removeItem(key);
|
|
||||||
} else {
|
|
||||||
localStorage.setItem(key, JSON.stringify(_state));
|
|
||||||
setState(_state);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DockviewPersistence = (props: { theme?: string }) => {
|
|
||||||
const [api, setApi] = React.useState<DockviewApi>();
|
|
||||||
const [layout, setLayout] =
|
|
||||||
useLocalStorage<SerializedDockview>('floating.layout');
|
|
||||||
|
|
||||||
const [disableFloatingGroups, setDisableFloatingGroups] =
|
|
||||||
React.useState<boolean>(false);
|
|
||||||
|
|
||||||
const load = (api: DockviewApi) => {
|
|
||||||
api.clear();
|
|
||||||
if (layout) {
|
|
||||||
try {
|
|
||||||
api.fromJSON(layout);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
api.clear();
|
|
||||||
loadDefaultLayout(api);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
loadDefaultLayout(api);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
|
||||||
load(event.api);
|
|
||||||
setApi(event.api);
|
|
||||||
};
|
|
||||||
|
|
||||||
const [options, setOptions] = React.useState<
|
|
||||||
'boundedWithinViewport' | undefined
|
|
||||||
>(undefined);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
height: '100%',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div style={{ height: '25px' }}>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
if (api) {
|
|
||||||
setLayout(api.toJSON());
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
if (api) {
|
|
||||||
load(api);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Load
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
api!.clear();
|
|
||||||
setLayout(null);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Clear
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
addFloatingPanel2(api!);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Add Floating Group
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
setOptions(
|
|
||||||
options === undefined
|
|
||||||
? 'boundedWithinViewport'
|
|
||||||
: undefined
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{`Bounds: ${options ? 'Within' : 'Overflow'}`}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
setDisableFloatingGroups((x) => !x);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{`${
|
|
||||||
disableFloatingGroups ? 'Enable' : 'Disable'
|
|
||||||
} floating groups`}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flexGrow: 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DockviewReact
|
|
||||||
onReady={onReady}
|
|
||||||
components={components}
|
|
||||||
watermarkComponent={Watermark}
|
|
||||||
leftHeaderActionsComponent={LeftComponent}
|
|
||||||
rightHeaderActionsComponent={RightComponent}
|
|
||||||
disableFloatingGroups={disableFloatingGroups}
|
|
||||||
floatingGroupBounds={options}
|
|
||||||
className={`${props.theme || 'dockview-theme-abyss'}`}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const LeftComponent = (props: IDockviewHeaderActionsProps) => {
|
|
||||||
const onClick = () => {
|
|
||||||
addPanel(props.containerApi);
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div style={{ height: '100%', color: 'white', padding: '0px 4px' }}>
|
|
||||||
<Icon onClick={onClick} icon={'add'} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const RightComponent = (props: IDockviewHeaderActionsProps) => {
|
|
||||||
const [floating, setFloating] = React.useState<boolean>(
|
|
||||||
props.api.location.type === 'floating'
|
|
||||||
);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const disposable = props.group.api.onDidLocationChange((event) => {
|
|
||||||
setFloating(event.location.type === 'floating');
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
disposable.dispose();
|
|
||||||
};
|
|
||||||
}, [props.group.api]);
|
|
||||||
|
|
||||||
const onClick = () => {
|
|
||||||
if (floating) {
|
|
||||||
const group = props.containerApi.addGroup();
|
|
||||||
props.group.api.moveTo({ group });
|
|
||||||
} else {
|
|
||||||
props.containerApi.addFloatingGroup(props.group, {
|
|
||||||
position: {
|
|
||||||
width: 400,
|
|
||||||
height: 300,
|
|
||||||
bottom: 50,
|
|
||||||
right: 50,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ height: '100%', color: 'white', padding: '0px 4px' }}>
|
|
||||||
<Icon
|
|
||||||
onClick={onClick}
|
|
||||||
icon={floating ? 'jump_to_element' : 'back_to_tab'}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DockviewPersistence;
|
|
||||||
|
|
||||||
const Watermark = () => {
|
|
||||||
return <div style={{ color: 'white', padding: '8px' }}>watermark</div>;
|
|
||||||
};
|
|
@ -1,20 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
export const Icon = (props: {
|
|
||||||
icon: string;
|
|
||||||
title?: string;
|
|
||||||
onClick?: (event: React.MouseEvent) => void;
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
title={props.title}
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
width: '30px',
|
|
||||||
height: '100%',
|
|
||||||
|
|
||||||
fontSize: '18px',
|
|
||||||
}}
|
|
||||||
onClick={props.onClick}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{ fontSize: 'inherit', cursor: 'pointer' }}
|
|
||||||
className="material-symbols-outlined"
|
|
||||||
>
|
|
||||||
{props.icon}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "dockview.group-actions",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.tsx",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview": "*",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/react": "^18.0.28",
|
|
||||||
"@types/react-dom": "^18.0.11",
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
||||||
<!--
|
|
||||||
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>
|
|
@ -1,20 +0,0 @@
|
|||||||
.dockview-groupcontrol-demo {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
color: white;
|
|
||||||
background-color: black;
|
|
||||||
padding: 0px 8px;
|
|
||||||
|
|
||||||
margin: 1px;
|
|
||||||
border: 1px dotted orange;
|
|
||||||
|
|
||||||
.dockview-groupcontrol-demo-group-active {
|
|
||||||
padding: 0px 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dockview-groupcontrol-demo-active-panel {
|
|
||||||
color: yellow;
|
|
||||||
padding: 0px 8px;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,102 +0,0 @@
|
|||||||
import {
|
|
||||||
DockviewReact,
|
|
||||||
DockviewReadyEvent,
|
|
||||||
IDockviewHeaderActionsProps,
|
|
||||||
IDockviewPanelProps,
|
|
||||||
} from 'dockview';
|
|
||||||
import * as React from 'react';
|
|
||||||
import './app.scss';
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
default: (props: IDockviewPanelProps<{ title: string; x?: number }>) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
color: 'gray',
|
|
||||||
height: '100%',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span>{`${props.api.title}`}</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const RightHeaderActions = (props: IDockviewHeaderActionsProps) => {
|
|
||||||
const isGroupActive = props.isGroupActive;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="dockview-groupcontrol-demo">
|
|
||||||
<span
|
|
||||||
className="dockview-groupcontrol-demo-group-active"
|
|
||||||
style={{
|
|
||||||
background: isGroupActive ? 'green' : 'red',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{isGroupActive ? 'Group Active' : 'Group Inactive'}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const LeftHeaderActions = (props: IDockviewHeaderActionsProps) => {
|
|
||||||
const activePanel = props.activePanel;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="dockview-groupcontrol-demo">
|
|
||||||
<span className="dockview-groupcontrol-demo-active-panel">{`activePanel: ${
|
|
||||||
activePanel?.id || 'null'
|
|
||||||
}`}</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const PrefixHeader = (props: IDockviewHeaderActionsProps) => {
|
|
||||||
const activePanel = props.activePanel;
|
|
||||||
|
|
||||||
return <div className="dockview-groupcontrol-demo">{'🌲'}</div>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const DockviewGroupControl = (props: { theme: string }) => {
|
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_1',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 1',
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_2',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 2',
|
|
||||||
position: {
|
|
||||||
direction: 'right',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
event.api.addPanel({
|
|
||||||
id: 'panel_3',
|
|
||||||
component: 'default',
|
|
||||||
title: 'Panel 3',
|
|
||||||
position: {
|
|
||||||
direction: 'below',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DockviewReact
|
|
||||||
onReady={onReady}
|
|
||||||
components={components}
|
|
||||||
prefixHeaderActionsComponent={PrefixHeader}
|
|
||||||
leftHeaderActionsComponent={LeftHeaderActions}
|
|
||||||
rightHeaderActionsComponent={RightHeaderActions}
|
|
||||||
className={`${props.theme || 'dockview-theme-abyss'}`}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DockviewGroupControl;
|
|
@ -1,20 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0px;
|
|
||||||
color: white;
|
|
||||||
font-family: sans-serif;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "dockview.layout",
|
|
||||||
"description": "",
|
|
||||||
"keywords": [
|
|
||||||
"dockview"
|
|
||||||
],
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.tsx",
|
|
||||||
"dependencies": {
|
|
||||||
"dockview": "*",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/react": "^18.0.28",
|
|
||||||
"@types/react-dom": "^18.0.11",
|
|
||||||
"typescript": "^4.9.5",
|
|
||||||
"react-scripts": "*"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test --env=jsdom",
|
|
||||||
"eject": "react-scripts eject"
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not ie <= 11",
|
|
||||||
"not op_mini all"
|
|
||||||
]
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user