mirror of
https://github.com/mathuo/dockview
synced 2025-09-14 21:27:53 +00:00
chore: latest docs
This commit is contained in:
parent
653fead20b
commit
a05f101ad4
29
packages/docs/blog/2022-06-12-dockview-1.5.0.mdx
Normal file
29
packages/docs/blog/2022-06-12-dockview-1.5.0.mdx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
slug: dockview-1.5.0-release
|
||||||
|
title: Dockview 1.5.0
|
||||||
|
tags: [release]
|
||||||
|
---
|
||||||
|
|
||||||
|
import Link from '@docusaurus/Link';
|
||||||
|
|
||||||
|
# Release Notes
|
||||||
|
|
||||||
|
## 🚀 Features
|
||||||
|
|
||||||
|
- Additional Themes [commit](https://github.com/mathuo/dockview/commit/1921e170e0b8275e8a10255f616119d36cff80cf)
|
||||||
|
- `dockview-theme-abyss` and `dockview-theme-dracula`
|
||||||
|
- SVG Icons [#132](https://github.com/mathuo/dockview/pull/132)
|
||||||
|
- Use inline SVG icons for the close and chevon icons to allow for easier customization and theming
|
||||||
|
- Dnd improvements [#136](https://github.com/mathuo/dockview/pull/136)
|
||||||
|
- Components always behaviour independant of one another by default, there is no cross component dnd behaviour unless manually set by user through `onDidDrop` and `showDndOverlay` props.
|
||||||
|
- Default tab [#136](https://github.com/mathuo/dockview/pull/136)
|
||||||
|
- Provide a default React tab implementation to allow for simple changes to tab renderer without rewritting the entire tab
|
||||||
|
- Override the default tab in `ReactDockview` with the `defaultTabComponent` prop
|
||||||
|
- Group controls renderer [#138](https://github.com/mathuo/dockview/pull/138)
|
||||||
|
- Provide the `groupControlComponent` prop in `ReactDockview` to create custom control components for groups. <Link to="../../docs/components/dockview/#group-controls-panel">Go</Link>
|
||||||
|
|
||||||
|
## 🛠 Miscs
|
||||||
|
|
||||||
|
- Various doc enhancements @ [dockview.dev](https://dockview.dev)
|
||||||
|
|
||||||
|
## 🔥 Breaking changes
|
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
sidebar_position: 1
|
sidebar_position: 1
|
||||||
|
description: How to get started with Dockview
|
||||||
---
|
---
|
||||||
|
|
||||||
import { SimpleSplitview } from '@site/src/components/simpleSplitview';
|
import { SimpleSplitview } from '@site/src/components/simpleSplitview';
|
||||||
|
@ -5,5 +5,5 @@
|
|||||||
"link": {
|
"link": {
|
||||||
"type": "generated-index",
|
"type": "generated-index",
|
||||||
"title": "Components"
|
"title": "Components"
|
||||||
},
|
}
|
||||||
}
|
}
|
@ -1,3 +1,7 @@
|
|||||||
|
---
|
||||||
|
description: Dockview Documentation
|
||||||
|
---
|
||||||
|
|
||||||
import { SimpleDockview } from '@site/src/components/simpleDockview';
|
import { SimpleDockview } from '@site/src/components/simpleDockview';
|
||||||
import {
|
import {
|
||||||
RenderingDockview,
|
RenderingDockview,
|
||||||
@ -6,6 +10,8 @@ import {
|
|||||||
import { DndDockview } from '@site/src/components/dockview/dnd';
|
import { DndDockview } from '@site/src/components/dockview/dnd';
|
||||||
import { EventsDockview } from '@site/src/components/dockview/events';
|
import { EventsDockview } from '@site/src/components/dockview/events';
|
||||||
import { ContextMenuDockview } from '@site/src/components/dockview/contextMenu';
|
import { ContextMenuDockview } from '@site/src/components/dockview/contextMenu';
|
||||||
|
import { NestedDockview } from '@site/src/components/dockview/nested';
|
||||||
|
import { CustomHeadersDockview } from '@site/src/components/dockview/customHeaders';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
|
|
||||||
# Dockview
|
# Dockview
|
||||||
@ -162,28 +168,55 @@ You may wish to hide the header section of a group. This can achieved through se
|
|||||||
panel.group.header.hidden = true;
|
panel.group.header.hidden = true;
|
||||||
```
|
```
|
||||||
|
|
||||||
### Context Menu
|
### Custom Tab Headers
|
||||||
|
|
||||||
Since overriding the context menu is a such a common feature rather than defining a custom tab the `ReactDockview` component exposes the prop `onTabContextMenu`.
|
You can provide custom renderers for your tab headers.
|
||||||
You can alternatively define a custom tab component for more granular control.
|
A default implementation of `DockviewDefaultTab` is provided should you only wish to attach minor
|
||||||
|
changes and events that do not alter the default behaviour, for example to add a custom context menu event
|
||||||
|
handler.
|
||||||
|
|
||||||
:::caution
|
You are also free to define a custom renderer entirely from scratch and not make use of the `DockviewDefaultTab` component.
|
||||||
|
|
||||||
The `onTabContextMenu` is intended to be removed in a future release to further simplify the library.
|
```tsx title="Attaching a custom context menu event handlers to a custom header"
|
||||||
In the future you will be required to define a custom tab component to intercept the context menu events.
|
import { IDockviewPanelHeaderProps, DockviewDefaultTab } from 'dockview';
|
||||||
|
|
||||||
:::
|
const MyCustomheader = (props: IDockviewPanelHeaderProps) => {
|
||||||
|
const onContextMenu = (event: React.MouseEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
alert('context menu');
|
||||||
|
};
|
||||||
|
return <DockviewDefaultTab onContextMenu={onContextMenu} {...props} />;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
<div
|
To use a custom renderer you can must register a collection of tab components
|
||||||
style={{
|
|
||||||
height: '300px',
|
```tsx
|
||||||
backgroundColor: 'rgb(30,30,30)',
|
const tabComponents = {
|
||||||
color: 'white',
|
myCustomHeader: MyCustomHeader,
|
||||||
margin: '20px 0px',
|
};
|
||||||
}}
|
|
||||||
>
|
return <DockviewReact tabComponents={tabComponents} ... />;
|
||||||
<ContextMenuDockview />
|
```
|
||||||
</div>
|
|
||||||
|
```tsx
|
||||||
|
api.addPanel({
|
||||||
|
id: 'panel_1',
|
||||||
|
component: 'default',
|
||||||
|
tabComponent: 'myCustomHeader', // <--
|
||||||
|
title: 'Panel 1',
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also override the default tab renderer which will be used when no `tabComponent` is provided to the `addPanel` function.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<DockviewReact defaultTabComponent={MyCustomHeader} ... />;
|
||||||
|
```
|
||||||
|
|
||||||
|
As a simple example the below attachs a custom event handler for the context menu on all tabs as a default tab renderer
|
||||||
|
|
||||||
|
<CustomHeadersDockview />
|
||||||
|
|
||||||
### Rendering
|
### Rendering
|
||||||
|
|
||||||
@ -280,7 +313,7 @@ return (
|
|||||||
<DockviewReact
|
<DockviewReact
|
||||||
components={components}
|
components={components}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
onDidDrop={onDidDrop}
|
onDidDrop={onDidDrop}
|
||||||
showDndOverlay={showDndOverlay}
|
showDndOverlay={showDndOverlay}
|
||||||
/>
|
/>
|
||||||
@ -292,3 +325,23 @@ return (
|
|||||||
### Events
|
### Events
|
||||||
|
|
||||||
<EventsDockview />
|
<EventsDockview />
|
||||||
|
|
||||||
|
### Nested Dockviews
|
||||||
|
|
||||||
|
You can safely create multiple dockview instances within one page and nest dockviews within other dockviews.
|
||||||
|
If you wish to interact with the drop event from one dockview instance in another dockview instance you can implement the `showDndOverlay` and `onDidDrop` props on `DockviewReact`.
|
||||||
|
|
||||||
|
<NestedDockview />
|
||||||
|
|
||||||
|
### Group Controls Panel
|
||||||
|
|
||||||
|
`DockviewReact` accepts a prop `groupControlComponent` which expects a React component whos props are `IDockviewGroupControlProps`.
|
||||||
|
This control will be rendered inside the header bar on the right hand side for each group of tabs.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const Component: React.FunctionComponent<IDockviewGroupControlProps> = () => {
|
||||||
|
return <div>{'...'}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
return <DockviewReact {...props} groupControlComponent={Component} />;
|
||||||
|
```
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
---
|
||||||
|
description: Gridview Documentation
|
||||||
|
---
|
||||||
|
|
||||||
import { SimpleGridview } from '@site/src/components/simpleGridview';
|
import { SimpleGridview } from '@site/src/components/simpleGridview';
|
||||||
import { EventsGridview } from '@site/src/components/gridview/events';
|
import { EventsGridview } from '@site/src/components/gridview/events';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
|
---
|
||||||
|
description: Paneview Documentation
|
||||||
|
---
|
||||||
|
|
||||||
import { SimplePaneview } from '@site/src/components/simplePaneview';
|
import { SimplePaneview } from '@site/src/components/simplePaneview';
|
||||||
import { CustomHeaderPaneview } from '@site/src/components/paneview/customHeader';
|
import { CustomHeaderPaneview } from '@site/src/components/paneview/customHeader';
|
||||||
import { DragAndDropPaneview } from '@site/src/components/paneview/dragAndDrop';
|
import { DragAndDropPaneview } from '@site/src/components/paneview/dragAndDrop';
|
||||||
|
import { SideBySidePaneview } from '@site/src/components/paneview/sideBySide';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
|
|
||||||
# Paneview
|
# Paneview
|
||||||
@ -87,7 +92,7 @@ SimplePaneview = () => {
|
|||||||
components={components}
|
components={components}
|
||||||
headerComponents={headerComponents}
|
headerComponents={headerComponents}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -268,3 +273,13 @@ const headerComponents = { myHeaderComponent: MyHeaderComponent };
|
|||||||
If you provide the `PaneviewReact` component with the prop `onDidDrop` you will be able to interact with custom drop events.
|
If you provide the `PaneviewReact` component with the prop `onDidDrop` you will be able to interact with custom drop events.
|
||||||
|
|
||||||
<DragAndDropPaneview />
|
<DragAndDropPaneview />
|
||||||
|
|
||||||
|
### Interactions
|
||||||
|
|
||||||
|
You can safely create multiple paneview instances within one page. They will not interact with each other by default.
|
||||||
|
|
||||||
|
If you wish to interact with the drop event from one paneview instance in another paneview instance you can implement the `showDndOverlay` and `onDidDrop` props on `PaneviewReact`.
|
||||||
|
|
||||||
|
As an example see how dragging a header from one control to another will only trigger an interactable event for the developer if the checkbox is enabled.
|
||||||
|
|
||||||
|
<SideBySidePaneview />
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
---
|
||||||
|
description: Splitview Documentation
|
||||||
|
---
|
||||||
|
|
||||||
import { SimpleSplitview } from '@site/src/components/simpleSplitview';
|
import { SimpleSplitview } from '@site/src/components/simpleSplitview';
|
||||||
import { SplitviewExample1 } from '@site/src/components/splitview/active';
|
import { SplitviewExample1 } from '@site/src/components/splitview/active';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
@ -65,7 +69,7 @@ export const SimpleSplitview = () => {
|
|||||||
components={components}
|
components={components}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
orientation={Orientation.HORIZONTAL}
|
orientation={Orientation.HORIZONTAL}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
25
packages/docs/docs/examples.mdx
Normal file
25
packages/docs/docs/examples.mdx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 4
|
||||||
|
description: Dockview examples
|
||||||
|
---
|
||||||
|
|
||||||
|
import { SimpleSplitview } from '@site/src/components/simpleSplitview';
|
||||||
|
import { SimpleGridview } from '@site/src/components/simpleGridview';
|
||||||
|
import { SimplePaneview } from '@site/src/components/simplePaneview';
|
||||||
|
import { SimpleDockview } from '@site/src/components/simpleDockview';
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
|
||||||
|
<iframe
|
||||||
|
src="https://codesandbox.io/embed/dockview-template-mdc9f7?fontsize=14&hidenavigation=1&theme=dark"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '500px',
|
||||||
|
border: 0,
|
||||||
|
borderRaduis: '4px',
|
||||||
|
overflow: 'hidden',
|
||||||
|
}}
|
||||||
|
title="dockview-template"
|
||||||
|
allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
|
||||||
|
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
||||||
|
></iframe>
|
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
sidebar_position: 0
|
sidebar_position: 0
|
||||||
|
description: A zero dependency layout manager built for React
|
||||||
---
|
---
|
||||||
|
|
||||||
import { SimpleSplitview } from '@site/src/components/simpleSplitview';
|
import { SimpleSplitview } from '@site/src/components/simpleSplitview';
|
||||||
@ -35,7 +36,7 @@ depending on your solution this might be:
|
|||||||
A dark and light theme are provided, one of these classes (or a custom theme) must be attached at any point above your components in the HTML tree. To cover the entire web page you might attach the class to the `body` component:
|
A dark and light theme are provided, one of these classes (or a custom theme) must be attached at any point above your components in the HTML tree. To cover the entire web page you might attach the class to the `body` component:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<body classname="dockview-theme-dark">
|
<body classname="dockview-theme-abyss">
|
||||||
...
|
...
|
||||||
</body>
|
</body>
|
||||||
<body classname="dockview-theme-light">
|
<body classname="dockview-theme-light">
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
sidebar_position: 3
|
sidebar_position: 3
|
||||||
|
description: Theming Dockview Components
|
||||||
---
|
---
|
||||||
|
|
||||||
import { CustomCSSDockview } from '@site/src/components/dockview/customCss';
|
import { CustomCSSDockview } from '@site/src/components/dockview/customCss';
|
||||||
@ -16,6 +17,14 @@ and depending can be imported
|
|||||||
@import './node_modules/dockview/dist/styles/dockview.css';
|
@import './node_modules/dockview/dist/styles/dockview.css';
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Provided themes
|
||||||
|
|
||||||
|
The following are provided as classes that you can attached to your components for themeing
|
||||||
|
|
||||||
|
- `.dockview-theme-light`
|
||||||
|
- `.dockview-theme-dark`
|
||||||
|
- `.dockview-theme-abyss`
|
||||||
|
|
||||||
## Customizing Theme
|
## Customizing Theme
|
||||||
|
|
||||||
`dockview` supports theming through the use of css properties.
|
`dockview` supports theming through the use of css properties.
|
||||||
|
@ -26,11 +26,13 @@
|
|||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"recoil": "^0.7.3-alpha.2",
|
"recoil": "^0.7.3-alpha.2",
|
||||||
|
"uuid": "^8.3.2",
|
||||||
"xml2js": "^0.4.23"
|
"xml2js": "^0.4.23"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@docusaurus/module-type-aliases": "2.0.0-beta.20",
|
"@docusaurus/module-type-aliases": "2.0.0-beta.20",
|
||||||
"@tsconfig/docusaurus": "^1.0.5",
|
"@tsconfig/docusaurus": "^1.0.5",
|
||||||
|
"@types/uuid": "^8.3.4",
|
||||||
"docusaurus-plugin-sass": "^0.2.2",
|
"docusaurus-plugin-sass": "^0.2.2",
|
||||||
"fs-extra": "^10.1.0",
|
"fs-extra": "^10.1.0",
|
||||||
"install": "^0.13.0",
|
"install": "^0.13.0",
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
.tab {
|
|
||||||
.dockview-react-tab {
|
|
||||||
display: flex;
|
|
||||||
padding: 0px 8px;
|
|
||||||
align-items: center;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.dockview-react-tab-title {
|
|
||||||
padding: 0px 8px;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dockview-react-tab-action {
|
|
||||||
padding: 0px 4px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-radius: 2px;
|
|
||||||
background-color: rgba(90, 93, 94, 0.31);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.dockview-inactive-tab:not(:hover) {
|
|
||||||
.dockview-react-tab-action {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,7 +6,6 @@ import {
|
|||||||
TabContextMenuEvent,
|
TabContextMenuEvent,
|
||||||
} from 'dockview';
|
} from 'dockview';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import './contextMenu.scss';
|
|
||||||
|
|
||||||
const components = {
|
const components = {
|
||||||
default: (props: IDockviewPanelProps<{ title: string }>) => {
|
default: (props: IDockviewPanelProps<{ title: string }>) => {
|
||||||
@ -108,7 +107,7 @@ export const ContextMenuDockview = () => {
|
|||||||
components={components}
|
components={components}
|
||||||
tabComponents={tabComponents}
|
tabComponents={tabComponents}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
onTabContextMenu={onContextMenu}
|
onTabContextMenu={onContextMenu}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
107
packages/docs/src/components/dockview/customHeaders.tsx
Normal file
107
packages/docs/src/components/dockview/customHeaders.tsx
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import {
|
||||||
|
DockviewDefaultTab,
|
||||||
|
DockviewReact,
|
||||||
|
DockviewReadyEvent,
|
||||||
|
IDockviewPanelHeaderProps,
|
||||||
|
IDockviewPanelProps,
|
||||||
|
} from 'dockview';
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
const components = {
|
||||||
|
default: (props: IDockviewPanelProps<{ title: string }>) => {
|
||||||
|
return <div style={{ padding: '20px' }}>{props.params.title}</div>;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const MyCustomheader = (props: IDockviewPanelHeaderProps) => {
|
||||||
|
const onContextMenu = (event: React.MouseEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
alert('context menu');
|
||||||
|
};
|
||||||
|
return <DockviewDefaultTab onContextMenu={onContextMenu} {...props} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const headerComponents = {
|
||||||
|
default: (props: IDockviewPanelHeaderProps) => {
|
||||||
|
const onContextMenu = (event: React.MouseEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
alert('context menu');
|
||||||
|
};
|
||||||
|
return <DockviewDefaultTab onContextMenu={onContextMenu} {...props} />;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CustomHeadersDockview = () => {
|
||||||
|
const onReady = (event: DockviewReadyEvent) => {
|
||||||
|
const d = localStorage.getItem('test');
|
||||||
|
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_1',
|
||||||
|
component: 'default',
|
||||||
|
title: 'Panel 1',
|
||||||
|
});
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_2',
|
||||||
|
component: 'default',
|
||||||
|
title: 'Panel 2',
|
||||||
|
});
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_3',
|
||||||
|
component: 'default',
|
||||||
|
title: 'Panel 3',
|
||||||
|
});
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_4',
|
||||||
|
component: 'default',
|
||||||
|
title: 'Panel 4',
|
||||||
|
position: { referencePanel: 'panel_3', direction: 'right' },
|
||||||
|
});
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_5',
|
||||||
|
component: 'default',
|
||||||
|
title: 'Panel 5',
|
||||||
|
position: { referencePanel: 'panel_4', direction: 'within' },
|
||||||
|
});
|
||||||
|
const panel6 = event.api.addPanel({
|
||||||
|
id: 'panel_6',
|
||||||
|
component: 'default',
|
||||||
|
title: 'Panel 6',
|
||||||
|
position: { referencePanel: 'panel_4', direction: 'below' },
|
||||||
|
});
|
||||||
|
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' },
|
||||||
|
});
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_8',
|
||||||
|
component: 'default',
|
||||||
|
|
||||||
|
title: 'Panel 8',
|
||||||
|
position: { referencePanel: 'panel_7', direction: 'within' },
|
||||||
|
});
|
||||||
|
|
||||||
|
event.api.addEmptyGroup();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '500px',
|
||||||
|
margin: '40px 0px',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DockviewReact
|
||||||
|
components={components}
|
||||||
|
defaultTabComponent={headerComponents.default}
|
||||||
|
onReady={onReady}
|
||||||
|
className="dockview-theme-abyss"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -13,3 +13,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
|
DockviewDefaultTab,
|
||||||
DockviewReact,
|
DockviewReact,
|
||||||
DockviewReadyEvent,
|
DockviewReadyEvent,
|
||||||
|
IDockviewPanelHeaderProps,
|
||||||
IDockviewPanelProps,
|
IDockviewPanelProps,
|
||||||
|
IDockviewGroupControlProps,
|
||||||
} from 'dockview';
|
} from 'dockview';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import * as ReactDOM from 'react-dom';
|
||||||
import { CURRENCIES, Currency, getCurrencies, getPrice } from './api';
|
import { CURRENCIES, Currency, getCurrencies, getPrice } from './api';
|
||||||
import './demo.scss';
|
import './demo.scss';
|
||||||
|
|
||||||
@ -114,19 +118,154 @@ const components = {
|
|||||||
news: News,
|
news: News,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const headerComponents = {
|
||||||
|
default: (props: IDockviewPanelHeaderProps) => {
|
||||||
|
const onContextMenu = (event: React.MouseEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
alert('context menu');
|
||||||
|
};
|
||||||
|
return <DockviewDefaultTab onContextMenu={onContextMenu} {...props} />;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
|
const Popover = (props: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
position?: { x: number; y: number };
|
||||||
|
close: () => void;
|
||||||
|
}) => {
|
||||||
|
const uuid = React.useMemo(() => v4(), []);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const listener = (event: KeyboardEvent) => {
|
||||||
|
if (event.key === 'Escape') {
|
||||||
|
props.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const listener2 = (event: MouseEvent) => {
|
||||||
|
let target = event.target;
|
||||||
|
|
||||||
|
while (target) {
|
||||||
|
if (target instanceof HTMLElement) {
|
||||||
|
if (target.classList.contains(uuid)) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
target = target.parentElement;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
target = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
props.close();
|
||||||
|
};
|
||||||
|
window.addEventListener('keypress', listener);
|
||||||
|
window.addEventListener('mousedown', listener2);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('keypress', listener);
|
||||||
|
window.removeEventListener('mousedown', listener2);
|
||||||
|
};
|
||||||
|
}, [props.close, uuid]);
|
||||||
|
|
||||||
|
if (!props.position) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReactDOM.createPortal(
|
||||||
|
<div
|
||||||
|
className={uuid}
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: props.position.y,
|
||||||
|
left: props.position.x,
|
||||||
|
background: 'white',
|
||||||
|
border: '1px solid black',
|
||||||
|
zIndex: 99,
|
||||||
|
padding: '10px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</div>,
|
||||||
|
document.body
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Icon = (props: {
|
||||||
|
icon: string;
|
||||||
|
onClick?: (event: React.MouseEvent) => void;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div className="action" onClick={props.onClick}>
|
||||||
|
<span
|
||||||
|
style={{ fontSize: 'inherit' }}
|
||||||
|
className="material-symbols-outlined"
|
||||||
|
>
|
||||||
|
{props.icon}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Button = () => {
|
||||||
|
const [position, setPosition] =
|
||||||
|
React.useState<{ x: number; y: number } | undefined>(undefined);
|
||||||
|
|
||||||
|
const close = () => setPosition(undefined);
|
||||||
|
|
||||||
|
const onClick = (event: React.MouseEvent) => {
|
||||||
|
setPosition({ x: event.pageX, y: event.pageY });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Icon icon="more_vert" onClick={onClick} />
|
||||||
|
{position && (
|
||||||
|
<Popover position={position} close={close}>
|
||||||
|
<div>hello</div>
|
||||||
|
</Popover>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const groupControlsComponents = {
|
||||||
|
panel_1: () => {
|
||||||
|
return <Icon icon="file_download" />;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const GroupControls = (props: IDockviewGroupControlProps) => {
|
||||||
|
const Component = React.useMemo(() => {
|
||||||
|
if (!props.isGroupActive || !props.activePanel) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return groupControlsComponents[props.activePanel.id];
|
||||||
|
}, [props.isGroupActive, props.activePanel]);
|
||||||
|
|
||||||
|
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 />}
|
||||||
|
<Button />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const DockviewDemo = () => {
|
export const DockviewDemo = () => {
|
||||||
const onReady = (event: DockviewReadyEvent) => {
|
const onReady = (event: DockviewReadyEvent) => {
|
||||||
// event.api.addPanel({
|
const d = localStorage.getItem('test');
|
||||||
// id: 'currencies',
|
|
||||||
// component: 'currencies',
|
|
||||||
// title: 'Prices',
|
|
||||||
// });
|
|
||||||
|
|
||||||
// event.api.addPanel({
|
|
||||||
// id: 'news',
|
|
||||||
// component: 'news',
|
|
||||||
// title: 'News',
|
|
||||||
// });
|
|
||||||
|
|
||||||
event.api.addPanel({
|
event.api.addPanel({
|
||||||
id: 'panel_1',
|
id: 'panel_1',
|
||||||
@ -175,10 +314,15 @@ export const DockviewDemo = () => {
|
|||||||
title: 'Panel 8',
|
title: 'Panel 8',
|
||||||
position: { referencePanel: 'panel_7', direction: 'within' },
|
position: { referencePanel: 'panel_7', direction: 'within' },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
event.api.addEmptyGroup();
|
||||||
|
|
||||||
|
event.api.getPanel('panel_1').api.setActive();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
id="homepage-dockview-demo"
|
||||||
style={{
|
style={{
|
||||||
height: '530px',
|
height: '530px',
|
||||||
margin: '40px 0px',
|
margin: '40px 0px',
|
||||||
@ -190,6 +334,8 @@ export const DockviewDemo = () => {
|
|||||||
<div style={{ flexGrow: 1 }}>
|
<div style={{ flexGrow: 1 }}>
|
||||||
<DockviewReact
|
<DockviewReact
|
||||||
components={components}
|
components={components}
|
||||||
|
defaultTabComponent={headerComponents.default}
|
||||||
|
groupControlComponent={GroupControls}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
className="dockview-theme-abyss"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
|
@ -26,45 +26,6 @@ const paneComponents = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const headerComponents = {
|
|
||||||
default: (props: IPaneviewPanelProps) => {
|
|
||||||
const [expanded, setExpanded] = React.useState<boolean>(
|
|
||||||
props.api.isExpanded
|
|
||||||
);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const disposable = props.api.onDidExpansionChange((event) =>
|
|
||||||
setExpanded(event.isExpanded)
|
|
||||||
);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
disposable.dispose();
|
|
||||||
};
|
|
||||||
}, [props.api]);
|
|
||||||
|
|
||||||
const onClick = () => props.api.setExpanded(!props.api.isExpanded);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
onClick={onClick}
|
|
||||||
style={{
|
|
||||||
background: '#1C1C2A',
|
|
||||||
height: '100%',
|
|
||||||
color: 'white',
|
|
||||||
padding: '0px 8px',
|
|
||||||
display: 'flex',
|
|
||||||
cursor: 'pointer',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span className="material-symbols-outlined">
|
|
||||||
{expanded ? 'expand_more' : 'chevron_right'}
|
|
||||||
</span>
|
|
||||||
{props.title}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const components = {
|
const components = {
|
||||||
default: (props: IGridviewPanelProps<{ title: string }>) => {
|
default: (props: IGridviewPanelProps<{ title: string }>) => {
|
||||||
return (
|
return (
|
||||||
@ -84,7 +45,6 @@ const components = {
|
|||||||
event.api.addPanel({
|
event.api.addPanel({
|
||||||
id: 'pane_1',
|
id: 'pane_1',
|
||||||
component: 'default',
|
component: 'default',
|
||||||
headerComponent: 'default',
|
|
||||||
title: 'Pane 1',
|
title: 'Pane 1',
|
||||||
isExpanded: false,
|
isExpanded: false,
|
||||||
});
|
});
|
||||||
@ -92,7 +52,6 @@ const components = {
|
|||||||
event.api.addPanel({
|
event.api.addPanel({
|
||||||
id: 'pane_2',
|
id: 'pane_2',
|
||||||
component: 'default',
|
component: 'default',
|
||||||
headerComponent: 'default',
|
|
||||||
title: 'Pane 2',
|
title: 'Pane 2',
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
});
|
});
|
||||||
@ -100,7 +59,6 @@ const components = {
|
|||||||
event.api.addPanel({
|
event.api.addPanel({
|
||||||
id: 'pane_3',
|
id: 'pane_3',
|
||||||
component: 'default',
|
component: 'default',
|
||||||
headerComponent: 'default',
|
|
||||||
title: 'Pane 3',
|
title: 'Pane 3',
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
});
|
});
|
||||||
@ -108,7 +66,6 @@ const components = {
|
|||||||
event.api.addPanel({
|
event.api.addPanel({
|
||||||
id: 'pane_4',
|
id: 'pane_4',
|
||||||
component: 'default',
|
component: 'default',
|
||||||
headerComponent: 'default',
|
|
||||||
title: 'Pane 4',
|
title: 'Pane 4',
|
||||||
isExpanded: false,
|
isExpanded: false,
|
||||||
});
|
});
|
||||||
@ -118,7 +75,6 @@ const components = {
|
|||||||
<PaneviewReact
|
<PaneviewReact
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
components={paneComponents}
|
components={paneComponents}
|
||||||
headerComponents={headerComponents}
|
|
||||||
className="paneview-background"
|
className="paneview-background"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -95,7 +95,7 @@ export const DndDockview = (props: { renderVisibleOnly: boolean }) => {
|
|||||||
<DockviewReact
|
<DockviewReact
|
||||||
components={components}
|
components={components}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
onDidDrop={onDidDrop}
|
onDidDrop={onDidDrop}
|
||||||
showDndOverlay={showDndOverlay}
|
showDndOverlay={showDndOverlay}
|
||||||
/>
|
/>
|
||||||
|
@ -332,7 +332,7 @@ export const EventsDockview = () => {
|
|||||||
<DockviewReact
|
<DockviewReact
|
||||||
components={components}
|
components={components}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
12
packages/docs/src/components/dockview/nested.scss
Normal file
12
packages/docs/src/components/dockview/nested.scss
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
.nested-dockview {
|
||||||
|
position: relative;
|
||||||
|
::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
height: 1px;
|
||||||
|
width: 100%;
|
||||||
|
background-color: var(--dv-separator-border);
|
||||||
|
}
|
||||||
|
}
|
101
packages/docs/src/components/dockview/nested.tsx
Normal file
101
packages/docs/src/components/dockview/nested.tsx
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import {
|
||||||
|
DockviewDndOverlayEvent,
|
||||||
|
DockviewDropEvent,
|
||||||
|
DockviewReact,
|
||||||
|
DockviewReadyEvent,
|
||||||
|
IDockviewPanelProps,
|
||||||
|
} from 'dockview';
|
||||||
|
import * as React from 'react';
|
||||||
|
import './nested.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="dockview-theme-abyss 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,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const NestedDockview = () => {
|
||||||
|
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 (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '500px',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DockviewReact
|
||||||
|
onReady={onReady}
|
||||||
|
components={components}
|
||||||
|
className="dockview-theme-abyss"
|
||||||
|
showDndOverlay={showDndOverlay}
|
||||||
|
onDidDrop={onDidDrop}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -137,7 +137,7 @@ export const RenderingDockview = (props: { renderVisibleOnly: boolean }) => {
|
|||||||
<DockviewReact
|
<DockviewReact
|
||||||
components={components}
|
components={components}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -329,7 +329,7 @@ export const EventsGridview = () => {
|
|||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
proportionalLayout={false}
|
proportionalLayout={false}
|
||||||
orientation={Orientation.VERTICAL}
|
orientation={Orientation.VERTICAL}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ export const CustomHeaderPaneview = () => {
|
|||||||
components={components}
|
components={components}
|
||||||
headerComponents={headerComponents}
|
headerComponents={headerComponents}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -94,7 +94,7 @@ export const DragAndDropPaneview = () => {
|
|||||||
components={components}
|
components={components}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
onDidDrop={onDidDrop}
|
onDidDrop={onDidDrop}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
11
packages/docs/src/components/paneview/sideBySide.scss
Normal file
11
packages/docs/src/components/paneview/sideBySide.scss
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
.paneview-side-by-side {
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
background-color: rgb(30, 30, 30);
|
||||||
|
color: white;
|
||||||
|
}
|
118
packages/docs/src/components/paneview/sideBySide.tsx
Normal file
118
packages/docs/src/components/paneview/sideBySide.tsx
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import {
|
||||||
|
IPaneviewPanelProps,
|
||||||
|
PaneviewDropEvent,
|
||||||
|
PaneviewReact,
|
||||||
|
PaneviewReadyEvent,
|
||||||
|
PaneviewDndOverlayEvent,
|
||||||
|
} from 'dockview';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Console, Line } from '../console/console';
|
||||||
|
import './sideBySide.scss';
|
||||||
|
|
||||||
|
const components = {
|
||||||
|
default: (props: IPaneviewPanelProps<{ title: string }>) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: '10px',
|
||||||
|
height: '100%',
|
||||||
|
backgroundColor: 'rgb(60,60,60)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.params.title}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SideBySidePaneview = () => {
|
||||||
|
const [checked, setChecked] = React.useState<boolean>(false);
|
||||||
|
const [lines, setLines] = React.useState<Line[]>([]);
|
||||||
|
|
||||||
|
const onReady = (event: PaneviewReadyEvent) => {
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_1',
|
||||||
|
component: 'default',
|
||||||
|
params: {
|
||||||
|
title: 'Panel 1',
|
||||||
|
},
|
||||||
|
title: 'Panel 1',
|
||||||
|
});
|
||||||
|
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_2',
|
||||||
|
component: 'default',
|
||||||
|
params: {
|
||||||
|
title: 'Panel 2',
|
||||||
|
},
|
||||||
|
title: 'Panel 2',
|
||||||
|
});
|
||||||
|
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_3',
|
||||||
|
component: 'default',
|
||||||
|
params: {
|
||||||
|
title: 'Panel 3',
|
||||||
|
},
|
||||||
|
title: 'Panel 3',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const showDndOverlay = (event: PaneviewDndOverlayEvent) => {
|
||||||
|
return checked;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDidDrop = (event: PaneviewDropEvent) => {
|
||||||
|
const text = `onDidDrop ${event.position} ${event.panel.id}`;
|
||||||
|
|
||||||
|
setLines((lines) => [...lines, { text, timestamp: new Date() }]);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '300px',
|
||||||
|
margin: '20px 0px',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ height: '25px' }}>
|
||||||
|
<label>
|
||||||
|
<span>Enable external events</span>
|
||||||
|
<input
|
||||||
|
type={'checkbox'}
|
||||||
|
checked={checked}
|
||||||
|
onChange={(e) => {
|
||||||
|
setChecked(e.target.checked);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '250px',
|
||||||
|
display: 'flex',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<PaneviewReact
|
||||||
|
components={components}
|
||||||
|
onReady={onReady}
|
||||||
|
className="dockview-theme-abyss paneview-side-by-side"
|
||||||
|
showDndOverlay={showDndOverlay}
|
||||||
|
onDidDrop={onDidDrop}
|
||||||
|
/>
|
||||||
|
<PaneviewReact
|
||||||
|
components={components}
|
||||||
|
onReady={onReady}
|
||||||
|
className="dockview-theme-abyss paneview-side-by-side"
|
||||||
|
showDndOverlay={showDndOverlay}
|
||||||
|
onDidDrop={onDidDrop}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ height: '100px' }}>
|
||||||
|
<Console lines={lines} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -110,7 +110,7 @@ export const SimpleDockview = () => {
|
|||||||
<DockviewReact
|
<DockviewReact
|
||||||
components={components}
|
components={components}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -93,7 +93,7 @@ export const SimpleGridview = () => {
|
|||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
proportionalLayout={false}
|
proportionalLayout={false}
|
||||||
orientation={Orientation.VERTICAL}
|
orientation={Orientation.VERTICAL}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -96,7 +96,7 @@ export const SimplePaneview = () => {
|
|||||||
components={components}
|
components={components}
|
||||||
headerComponents={headerComponents}
|
headerComponents={headerComponents}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -48,7 +48,7 @@ export const SimpleSplitview = (props: { proportional?: boolean }) => {
|
|||||||
proportionalLayout={props.proportional}
|
proportionalLayout={props.proportional}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
orientation={Orientation.HORIZONTAL}
|
orientation={Orientation.HORIZONTAL}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -130,7 +130,7 @@ export const SplitviewExample1 = (props: { proportional?: boolean }) => {
|
|||||||
proportionalLayout={props.proportional}
|
proportionalLayout={props.proportional}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
orientation={Orientation.HORIZONTAL}
|
orientation={Orientation.HORIZONTAL}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ height: '20px', display: 'flex' }}>
|
<div style={{ height: '20px', display: 'flex' }}>
|
||||||
|
@ -280,7 +280,7 @@ return (
|
|||||||
<DockviewReact
|
<DockviewReact
|
||||||
components={components}
|
components={components}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
onDidDrop={onDidDrop}
|
onDidDrop={onDidDrop}
|
||||||
showDndOverlay={showDndOverlay}
|
showDndOverlay={showDndOverlay}
|
||||||
/>
|
/>
|
||||||
|
@ -87,7 +87,7 @@ SimplePaneview = () => {
|
|||||||
components={components}
|
components={components}
|
||||||
headerComponents={headerComponents}
|
headerComponents={headerComponents}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -65,7 +65,7 @@ export const SimpleSplitview = () => {
|
|||||||
components={components}
|
components={components}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
orientation={Orientation.HORIZONTAL}
|
orientation={Orientation.HORIZONTAL}
|
||||||
className="dockview-theme-dark"
|
className="dockview-theme-abyss"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -35,7 +35,7 @@ depending on your solution this might be:
|
|||||||
A dark and light theme are provided, one of these classes (or a custom theme) must be attached at any point above your components in the HTML tree. To cover the entire web page you might attach the class to the `body` component:
|
A dark and light theme are provided, one of these classes (or a custom theme) must be attached at any point above your components in the HTML tree. To cover the entire web page you might attach the class to the `body` component:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<body classname="dockview-theme-dark">
|
<body classname="dockview-theme-abyss">
|
||||||
...
|
...
|
||||||
</body>
|
</body>
|
||||||
<body classname="dockview-theme-light">
|
<body classname="dockview-theme-light">
|
||||||
|
119
packages/docs/versioned_docs/version-1.5.0/basics.mdx
vendored
Normal file
119
packages/docs/versioned_docs/version-1.5.0/basics.mdx
vendored
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 1
|
||||||
|
description: How to get started with Dockview
|
||||||
|
---
|
||||||
|
|
||||||
|
import { SimpleSplitview } from '@site/src/components/simpleSplitview';
|
||||||
|
import { SimpleSplitview2 } from '@site/src/components/simpleSplitview2';
|
||||||
|
|
||||||
|
# Basics
|
||||||
|
|
||||||
|
asd
|
||||||
|
This section will take you through a number of concepts that can be applied to all dockview components.
|
||||||
|
|
||||||
|
## Panels
|
||||||
|
|
||||||
|
The below examples use `ReactSplitview` but the logic holds for `ReactPaneview`, `ReactGridview` and `ReactDockview` using their respective implementations and interfaces.
|
||||||
|
All components require you to provide an `onReady` prop which you can use to build and control your component.
|
||||||
|
|
||||||
|
### Adding a panel with parameters
|
||||||
|
|
||||||
|
You can pass parameters to a panel through the `params` object
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const onReady = (event: SplitviewReadyEvent) => {
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_1',
|
||||||
|
component: 'myComponent',
|
||||||
|
params: {
|
||||||
|
title: 'My Title',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
and you can access those properties through the `props.params` object. The TypeScript interface accepts an optional generic type `T` that corresponds to the params objects type.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const MyComponent = (props: ISplitviewPanelProps<{ title: string }>) => {
|
||||||
|
return <div>{`My first panel has the title: ${props.params.title}`}</div>;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
There are two types of API you will interact with using `dockview`.
|
||||||
|
|
||||||
|
- The `panel API` is accessible via `props.api` in user defined panels and via the `.api` variable found on panel instances. This API contains actions and variable related to the the individual panel.
|
||||||
|
- The `container API` is accessible via `event.api` in the `onReady` events and `props.containerApi` in user defined panels. This API contains actions and variable related to the component as a whole.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const MyComponent = (props: ISplitviewPanelProps<{ title: string }>) => {
|
||||||
|
React.useEffect(() => {
|
||||||
|
const disposable = props.api.onDidActiveChange((event) => {
|
||||||
|
console.log(`is panel active: ${event.isActive}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
disposable.dispose(); // remember to dispose of any subscriptions
|
||||||
|
};
|
||||||
|
}, [props.api]);
|
||||||
|
|
||||||
|
const addAnotherPanel = React.useCallback(() => {
|
||||||
|
props.containerApi.addPanel({
|
||||||
|
id: 'another_id',
|
||||||
|
component: 'anotherComponent',
|
||||||
|
});
|
||||||
|
}, [props.containerApi]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<span>{`My first panel has the title: ${props.params.title}`}</span>
|
||||||
|
<button onClick={addAnotherPanel}>Add Panel</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Serialization
|
||||||
|
|
||||||
|
All components support `toJSON(): T` which returns a Typed object representation of the components state. This same Typed object can be used to deserialize a view using `fromJSON(object: T): void`.
|
||||||
|
|
||||||
|
## Auto resizing
|
||||||
|
|
||||||
|
`SplitviewReact`, `GridviewReact`, `PaneviewReact` and `DockviewReact` will all automatically resize to fill the size of their parent element.
|
||||||
|
Internally this is achieved using a [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) which some users may need to polyfill.
|
||||||
|
You can disable this by settings the `disableAutoResizing` prop to be `true`.
|
||||||
|
|
||||||
|
You can manually resize a component using the API method `layout(width: number, height: number): void`.
|
||||||
|
An advanced case may use this in conjunction with `disableAutoResizing=true` to allow a parent component to have ultimate control over the dimensions of the component.
|
||||||
|
|
||||||
|
## Events
|
||||||
|
|
||||||
|
Many API properties can be listened on using the `Event` pattern. For example `api.onDidFocusChange(() => {...})`.
|
||||||
|
You should dispose of any event listeners you create cleaning up any listeners you would have created.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
React.useEffect(() => {
|
||||||
|
const disposable = api.onDidFocusChange(() => {
|
||||||
|
// write some code
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
disposable.dispose();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Proportional layout
|
||||||
|
|
||||||
|
The `proportionalLayout` property indicates the expected behaviour of the component as it's container resizes, should all views resize equally or should just one view expand to fill the new space. `proportionalLayout` can be set as a property on `SplitviewReact` and `GridviewReact` components.
|
||||||
|
Although not configurable on `DockviewReact` and `PaneviewReact` these both behave as if `proportionalLayout=true` was set for them.
|
||||||
|
|
||||||
|
<SimpleSplitview2 proportional={false} />
|
||||||
|
|
||||||
|
<SimpleSplitview2 proportional={true} />
|
||||||
|
|
||||||
|
## Browser support
|
||||||
|
|
||||||
|
dockview is intended to support all major browsers. Some users may require a polyfill for [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).
|
9
packages/docs/versioned_docs/version-1.5.0/components/_category_.json
vendored
Normal file
9
packages/docs/versioned_docs/version-1.5.0/components/_category_.json
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"label": "Components",
|
||||||
|
"collapsible": true,
|
||||||
|
"collapsed": false,
|
||||||
|
"link": {
|
||||||
|
"type": "generated-index",
|
||||||
|
"title": "Components"
|
||||||
|
}
|
||||||
|
}
|
347
packages/docs/versioned_docs/version-1.5.0/components/dockview.mdx
vendored
Normal file
347
packages/docs/versioned_docs/version-1.5.0/components/dockview.mdx
vendored
Normal file
@ -0,0 +1,347 @@
|
|||||||
|
---
|
||||||
|
description: Dockview Documentation
|
||||||
|
---
|
||||||
|
|
||||||
|
import { SimpleDockview } from '@site/src/components/simpleDockview';
|
||||||
|
import {
|
||||||
|
RenderingDockview,
|
||||||
|
Checkbox,
|
||||||
|
} from '@site/src/components/dockview/rendering';
|
||||||
|
import { DndDockview } from '@site/src/components/dockview/dnd';
|
||||||
|
import { EventsDockview } from '@site/src/components/dockview/events';
|
||||||
|
import { ContextMenuDockview } from '@site/src/components/dockview/contextMenu';
|
||||||
|
import { NestedDockview } from '@site/src/components/dockview/nested';
|
||||||
|
import { CustomHeadersDockview } from '@site/src/components/dockview/customHeaders';
|
||||||
|
import Link from '@docusaurus/Link';
|
||||||
|
|
||||||
|
# Dockview
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
Dockview is an abstraction built on top of [Gridviews](./gridview) where each view is a container of many tabbed panels.
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '300px',
|
||||||
|
backgroundColor: 'rgb(30,30,30)',
|
||||||
|
color: 'white',
|
||||||
|
margin: '20px 0px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SimpleDockview />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
You can access the panels associated group through the `panel.group` variable.
|
||||||
|
The group will always be defined and will change if a panel is moved into another group.
|
||||||
|
|
||||||
|
## DockviewReact Component
|
||||||
|
|
||||||
|
You can create a Dockview through the use of the `ReactDockview` component.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { ReactDockview } from 'dockview';
|
||||||
|
```
|
||||||
|
|
||||||
|
| Property | Type | Optional | Default | Description |
|
||||||
|
| ------------------- | ------------------------------------ | -------- | ------- | ------------------------------------------------------------ |
|
||||||
|
| onReady | (event: SplitviewReadyEvent) => void | No | | |
|
||||||
|
| components | object | No | | |
|
||||||
|
| tabComponents | object | Yes | | |
|
||||||
|
| watermarkComponent | object | Yes | | |
|
||||||
|
| hideBorders | boolean | Yes | false | |
|
||||||
|
| className | string | Yes | '' | |
|
||||||
|
| disableAutoResizing | boolean | Yes | false | See <Link to="../basics/#auto-resizing">Auto Resizing</Link> |
|
||||||
|
| onTabContextMenu | Event | Yes | false | |
|
||||||
|
| onDidDrop | Event | Yes | false | |
|
||||||
|
| showDndOverlay | Event | Yes | false | |
|
||||||
|
|
||||||
|
## Dockview API
|
||||||
|
|
||||||
|
The Dockview API is exposed both at the `onReady` event and on each panel through `props.containerApi`.
|
||||||
|
Through this API you can control general features of the component and access all added panels.
|
||||||
|
|
||||||
|
```tsx title="Dockview API via Panel component"
|
||||||
|
const MyComponent = (props: IDockviewPanelProps<{ title: string }>) => {
|
||||||
|
// props.containerApi...
|
||||||
|
|
||||||
|
return <div>{`My first panel has the title: ${props.params.title}`}</div>;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
```tsx title="Dockview API via the onReady callback"
|
||||||
|
const onReady = (event: DockviewReadyEvent) => {
|
||||||
|
// event.api...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
| Property | Type | Description |
|
||||||
|
| ---------------------- | ---------------------------------------------------- | -------------------------------------------------------- |
|
||||||
|
| height | `number` | Component pixel height |
|
||||||
|
| width | `number` | Component pixel width |
|
||||||
|
| minimumHeight | `number` | |
|
||||||
|
| maximumHeight | `number` | |
|
||||||
|
| maximumWidth | `number` | |
|
||||||
|
| maximumWidth | `number` | |
|
||||||
|
| length | `number` | Number of panels |
|
||||||
|
| size | `number` | Number of Groups |
|
||||||
|
| panels | `IDockviewPanel[]` | |
|
||||||
|
| groups | `GroupPanel[]` | |
|
||||||
|
| activePanel | `IDockviewPanel \| undefined` | |
|
||||||
|
| activeGroup | `IDockviewPanel \| undefined` | |
|
||||||
|
| | | |
|
||||||
|
| onDidLayoutChange | `Event<void>` | |
|
||||||
|
| onDidLayoutFromJSON | `Event<void>` | |
|
||||||
|
| onDidAddGroup | `Event<GroupPanel>` | |
|
||||||
|
| onDidRemoveGroup | `Event<GroupPanel>` | |
|
||||||
|
| onDidActiveGroupChange | `Event<GroupPanel \| undefined>` | |
|
||||||
|
| onDidAddPanel | `Event<IDockviewPanel>` | |
|
||||||
|
| onDidRemovePanel | `Event<IDockviewPanel>` | |
|
||||||
|
| onDidActivePanelChange | `Event<IDockviewPanel \| undefined>` | |
|
||||||
|
| onDidDrop | `Event<DockviewDropEvent` | |
|
||||||
|
| | | |
|
||||||
|
| addPanel | `addPanel(options: AddPanelOptions): IDockviewPanel` | |
|
||||||
|
| getPanel | `(id: string) \| IDockviewPanel \| undefined` | |
|
||||||
|
| addEmptyGroup | `(options? AddGroupOptions): void` | |
|
||||||
|
| closeAllGroups | `(): void` | |
|
||||||
|
| removeGroup | `(group: GroupPanel): void` | |
|
||||||
|
| getGroup | `(id: string): GroupPanel \| undefined` | |
|
||||||
|
| | | |
|
||||||
|
| getTabHeight | `(): number \| undefined` | |
|
||||||
|
| setTabHeight | `(hegiht: number \| undefined): void` | |
|
||||||
|
| updateOptions | `(options:SplitviewComponentUpdateOptions): void` | |
|
||||||
|
| focus | `(): void` | |
|
||||||
|
| layout | `(width: number, height:number): void` | <Link to="../basics/#auto-resizing">Auto Resizing</Link> |
|
||||||
|
| fromJSON | `(data: SerializedDockview): void` | <Link to="../basics/#serialization">Serialization</Link> |
|
||||||
|
| toJSON | `(): SerializedDockview` | <Link to="../basics/#serialization">Serialization</Link> |
|
||||||
|
| clear | `(): void` | Clears the current layout |
|
||||||
|
|
||||||
|
## Dockview Panel API
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const MyComponent = (props: IDockviewPanelProps<{ title: string }>) => {
|
||||||
|
// props.api...
|
||||||
|
|
||||||
|
return <div>{`My first panel has the title: ${props.params.title}`}</div>;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
| Property | Type | Description |
|
||||||
|
| ---------------------- | ----------------------------------------------------------- | --------------- |
|
||||||
|
| id | `string` | Panel id |
|
||||||
|
| isFocused | `boolean` | Is panel focsed |
|
||||||
|
| isActive | `boolean` | Is panel active |
|
||||||
|
| width | `number` | Panel width |
|
||||||
|
| height | `number` | Panel height |
|
||||||
|
| onDidDimensionsChange | `Event<PanelDimensionChangeEvent>` | |
|
||||||
|
| onDidFocusChange | `Event<FocusEvent>` | |
|
||||||
|
| onDidVisibilityChange | `Event<VisibilityEvent>` | |
|
||||||
|
| onDidActiveChange | `Event<ActiveEvent>` | |
|
||||||
|
| setActive | `(): void` | |
|
||||||
|
| | | |
|
||||||
|
| onDidConstraintsChange | `onDidConstraintsChange: Event<PanelConstraintChangeEvent>` | |
|
||||||
|
| setConstraints | `(value: PanelConstraintChangeEvent2): void;` | |
|
||||||
|
| setSize | `(event: SizeEvent): void` | |
|
||||||
|
| | | |
|
||||||
|
| group | `GroupPanel | undefined` |
|
||||||
|
| isGroupActive | `boolean` | |
|
||||||
|
| title | `string` | |
|
||||||
|
| suppressClosable | `boolean` | |
|
||||||
|
| close | `(): void` | |
|
||||||
|
| setTitle | `(title: string): void` | |
|
||||||
|
|
||||||
|
## Advanced Features
|
||||||
|
|
||||||
|
### Locked group
|
||||||
|
|
||||||
|
Locking a group will disable all drop events for this group ensuring a user can not add additional panels to the group.
|
||||||
|
You can still add groups to a locked panel programatically using the API.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
panel.group.locked = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Group header
|
||||||
|
|
||||||
|
You may wish to hide the header section of a group. This can achieved through setting the `hidden` variable on `panel.group.header`.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
panel.group.header.hidden = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Tab Headers
|
||||||
|
|
||||||
|
You can provide custom renderers for your tab headers.
|
||||||
|
A default implementation of `DockviewDefaultTab` is provided should you only wish to attach minor
|
||||||
|
changes and events that do not alter the default behaviour, for example to add a custom context menu event
|
||||||
|
handler.
|
||||||
|
|
||||||
|
You are also free to define a custom renderer entirely from scratch and not make use of the `DockviewDefaultTab` component.
|
||||||
|
|
||||||
|
```tsx title="Attaching a custom context menu event handlers to a custom header"
|
||||||
|
import { IDockviewPanelHeaderProps, DockviewDefaultTab } from 'dockview';
|
||||||
|
|
||||||
|
const MyCustomheader = (props: IDockviewPanelHeaderProps) => {
|
||||||
|
const onContextMenu = (event: React.MouseEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
alert('context menu');
|
||||||
|
};
|
||||||
|
return <DockviewDefaultTab onContextMenu={onContextMenu} {...props} />;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
To use a custom renderer you can must register a collection of tab components
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const tabComponents = {
|
||||||
|
myCustomHeader: MyCustomHeader,
|
||||||
|
};
|
||||||
|
|
||||||
|
return <DockviewReact tabComponents={tabComponents} ... />;
|
||||||
|
```
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
api.addPanel({
|
||||||
|
id: 'panel_1',
|
||||||
|
component: 'default',
|
||||||
|
tabComponent: 'myCustomHeader', // <--
|
||||||
|
title: 'Panel 1',
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also override the default tab renderer which will be used when no `tabComponent` is provided to the `addPanel` function.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<DockviewReact defaultTabComponent={MyCustomHeader} ... />;
|
||||||
|
```
|
||||||
|
|
||||||
|
As a simple example the below attachs a custom event handler for the context menu on all tabs as a default tab renderer
|
||||||
|
|
||||||
|
<CustomHeadersDockview />
|
||||||
|
|
||||||
|
### Rendering
|
||||||
|
|
||||||
|
Although `DockviewReact` will only add those tabs that are visible to the DOM all associated React Components for each tab including those that
|
||||||
|
are not initially visible will be created.
|
||||||
|
This will mean that any hooks in those components will run and if you running expensive operations in the tabs you may end up doing a lot of initial
|
||||||
|
work for what are hidden tabs.
|
||||||
|
|
||||||
|
This is the default behaviour to ensure the greatest flexibility for the user but you can create a Higher-Order component wrapping your components that
|
||||||
|
will ensure the component is only created if the tab is visible as below:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { PanelApi } from 'dockview';
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
function RenderWhenVisible<
|
||||||
|
T extends { api: Pick<PanelApi, 'isVisible' | 'onDidVisibilityChange'> }
|
||||||
|
>(component: React.FunctionComponent<T>) {
|
||||||
|
const HigherOrderComponent = (props: T) => {
|
||||||
|
const [visible, setVisible] = React.useState<boolean>(
|
||||||
|
props.api.isVisible
|
||||||
|
);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const disposable = props.api.onDidVisibilityChange((event) =>
|
||||||
|
setVisible(event.isVisible)
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
disposable.dispose();
|
||||||
|
};
|
||||||
|
}, [props.api]);
|
||||||
|
|
||||||
|
if (!visible) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return React.createElement(component, props);
|
||||||
|
};
|
||||||
|
return HigherOrderComponent;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const component = RenderWhenVisible(MyComponent);
|
||||||
|
```
|
||||||
|
|
||||||
|
Through toggling the checkbox you can see that when you only render those panels which are visible the underling React component is destroyed when it becomes hidden and re-created when it becomes visible.
|
||||||
|
|
||||||
|
<Checkbox />
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '300px',
|
||||||
|
backgroundColor: 'rgb(30,30,30)',
|
||||||
|
color: 'white',
|
||||||
|
margin: '20px 0px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<RenderingDockview renderVisibleOnly={false} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### Drag And Drop
|
||||||
|
|
||||||
|
The component exposes some method to help determine whether external drag events should be interacted with or not.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
/**
|
||||||
|
* called when an ondrop event which does not originate from the dockview libray and
|
||||||
|
* passes the showDndOverlay condition occurs
|
||||||
|
**/
|
||||||
|
const onDidDrop = (event: DockviewDropEvent) => {
|
||||||
|
const { group } = event;
|
||||||
|
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'test',
|
||||||
|
component: 'default',
|
||||||
|
position: {
|
||||||
|
referencePanel: group.activePanel.id,
|
||||||
|
direction: 'within',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* called for drag over events which do not originate from the dockview library
|
||||||
|
* allowing the developer to decide where the overlay should be shown for a
|
||||||
|
* particular drag event
|
||||||
|
**/
|
||||||
|
const showDndOverlay = (event: DockviewDndOverlayEvent) => {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DockviewReact
|
||||||
|
components={components}
|
||||||
|
onReady={onReady}
|
||||||
|
className="dockview-theme-abyss"
|
||||||
|
onDidDrop={onDidDrop}
|
||||||
|
showDndOverlay={showDndOverlay}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
<DndDockview />
|
||||||
|
|
||||||
|
### Events
|
||||||
|
|
||||||
|
<EventsDockview />
|
||||||
|
|
||||||
|
### Nested Dockviews
|
||||||
|
|
||||||
|
You can safely create multiple dockview instances within one page and nest dockviews within other dockviews.
|
||||||
|
If you wish to interact with the drop event from one dockview instance in another dockview instance you can implement the `showDndOverlay` and `onDidDrop` props on `DockviewReact`.
|
||||||
|
|
||||||
|
<NestedDockview />
|
||||||
|
|
||||||
|
### Group Controls Panel
|
||||||
|
|
||||||
|
`DockviewReact` accepts a prop `groupControlComponent` which expects a React component whos props are `IDockviewGroupControlProps`.
|
||||||
|
This control will be rendered inside the header bar on the right hand side for each group of tabs.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const Component: React.FunctionComponent<IDockviewGroupControlProps> = () => {
|
||||||
|
return <div>{'...'}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
return <DockviewReact {...props} groupControlComponent={Component} />;
|
||||||
|
```
|
120
packages/docs/versioned_docs/version-1.5.0/components/gridview.mdx
vendored
Normal file
120
packages/docs/versioned_docs/version-1.5.0/components/gridview.mdx
vendored
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
---
|
||||||
|
description: Gridview Documentation
|
||||||
|
---
|
||||||
|
|
||||||
|
import { SimpleGridview } from '@site/src/components/simpleGridview';
|
||||||
|
import { EventsGridview } from '@site/src/components/gridview/events';
|
||||||
|
import Link from '@docusaurus/Link';
|
||||||
|
|
||||||
|
# Gridview
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '300px',
|
||||||
|
backgroundColor: 'rgb(30,30,30)',
|
||||||
|
color: 'white',
|
||||||
|
margin: '20px 0px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SimpleGridview />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## GridviewReact Component
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { ReactGridview } from 'dockview';
|
||||||
|
```
|
||||||
|
|
||||||
|
| Property | Type | Optional | Default | Description |
|
||||||
|
| ------------------- | ------------------------------------ | -------- | ---------------------- | ------------------------------------------------------------------------ |
|
||||||
|
| onReady | (event: SplitviewReadyEvent) => void | No | | |
|
||||||
|
| components | object | No | | |
|
||||||
|
| orientation | Orientation | Yes | Orientation.HORIZONTAL | |
|
||||||
|
| proportionalLayout | boolean | Yes | true | See <Link to="../basics/#proportional-layout">Proportional layout</Link> |
|
||||||
|
| hideBorders | boolean | Yes | false | |
|
||||||
|
| className | string | Yes | '' | |
|
||||||
|
| disableAutoResizing | boolean | Yes | false | See <Link to="../basics/#auto-resizing">Auto Resizing</Link> |
|
||||||
|
|
||||||
|
## Gridview API
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const MyComponent = (props: IGridviewPanelProps<{ title: string }>) => {
|
||||||
|
// props.containerApi...
|
||||||
|
|
||||||
|
return <div>{`My first panel has the title: ${props.params.title}`}</div>;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const onReady = (event: GridviewReadyEvent) => {
|
||||||
|
// event.api...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
| Property | Type | Description |
|
||||||
|
| ---------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
|
||||||
|
| height | `number` | Component pixel height |
|
||||||
|
| width | `number` | Component pixel width |
|
||||||
|
| minimumHeight | `number` | |
|
||||||
|
| maximumHeight | `number` | |
|
||||||
|
| maximumWidth | `number` | |
|
||||||
|
| maximumWidth | `number` | |
|
||||||
|
| length | `number` | Number of panels |
|
||||||
|
| panels | `ISplitviewPanel[]` | all panels |
|
||||||
|
| orientation | `Orientation` | |
|
||||||
|
| | | |
|
||||||
|
| onDidLayoutChange | `Event<void>` | Fires on layout change |
|
||||||
|
| onDidLayoutFromJSON | `Event<void>` | Fires of layout change caused by a fromJSON deserialization call |
|
||||||
|
| onDidAddPanel | `Event<IGridviewPanel>` | Fires when a view is added |
|
||||||
|
| onDidRemovePanel | `Event<IGridviewPanel>` | Fires when a view is removed |
|
||||||
|
| onDidActivePanelChange | `Event<IGridviewPanel \| undefined>` | Fires when the active group changes |
|
||||||
|
| | | |
|
||||||
|
| addPanel | `addPanel(options: AddComponentOptions): IGridviewPanel` | |
|
||||||
|
| removePanel | `(panel: IGridviewPanel, sizing?: Sizing): void` | |
|
||||||
|
| movePanel | `(panel: IGridviewPanel, options: {direction: Direction, refernece:string, size?: number}): void` | |
|
||||||
|
| getPanel | `(id: string) \| IGridviewPanel \| undefined` | |
|
||||||
|
| | | |
|
||||||
|
| updateOptions | `(options:SplitviewComponentUpdateOptions): void` | |
|
||||||
|
| focus | `(): void` | Focus the active panel, if exists |
|
||||||
|
| layout | `(width: number, height:number): void` | <Link to="../basics/#auto-resizing">Auto Resizing</Link> |
|
||||||
|
| fromJSON | `(data: SerializedGridview): void` | <Link to="../basics/#serialization">Serialization</Link> |
|
||||||
|
| toJSON | `(): SerializedGridview` | <Link to="../basics/#serialization">Serialization</Link> |
|
||||||
|
| clear | `(): void` | Clears the current layout |
|
||||||
|
|
||||||
|
## Gridview Panel API
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const MyComponent = (props: IGridviewPanelProps<{ title: string }>) => {
|
||||||
|
// props.api...
|
||||||
|
|
||||||
|
return <div>{`My first panel has the title: ${props.params.title}`}</div>;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
| Property | Type | Description |
|
||||||
|
| ---------------------- | ----------------------------------------------------------- | ---------------- |
|
||||||
|
| id | `string` | Panel id |
|
||||||
|
| isFocused | `boolean` | Is panel focsed |
|
||||||
|
| isActive | `boolean` | Is panel active |
|
||||||
|
| isVisible | `boolean` | Is panel visible |
|
||||||
|
| width | `number` | Panel width |
|
||||||
|
| height | `number` | Panel height |
|
||||||
|
| | | |
|
||||||
|
| onDidDimensionsChange | `Event<PanelDimensionChangeEvent>` | |
|
||||||
|
| onDidFocusChange | `Event<FocusEvent>` | |
|
||||||
|
| onDidVisibilityChange | `Event<VisibilityEvent>` | |
|
||||||
|
| onDidActiveChange | `Event<ActiveEvent>` | |
|
||||||
|
| onDidConstraintsChange | `onDidConstraintsChange: Event<PanelConstraintChangeEvent>` | |
|
||||||
|
| | | |
|
||||||
|
| setVisible | `(isVisible: boolean): void` | |
|
||||||
|
| setActive | `(): void` | |
|
||||||
|
| setConstraints | `(value: PanelConstraintChangeEvent2): void;` | |
|
||||||
|
| setSize | `(event: SizeEvent): void` | |
|
||||||
|
|
||||||
|
## Events
|
||||||
|
|
||||||
|
`GridviewReact` exposes a number of events that the developer can listen to and below is a simple example with a log panel showing those events that occur.
|
||||||
|
|
||||||
|
<EventsGridview />
|
285
packages/docs/versioned_docs/version-1.5.0/components/paneview.mdx
vendored
Normal file
285
packages/docs/versioned_docs/version-1.5.0/components/paneview.mdx
vendored
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
---
|
||||||
|
description: Paneview Documentation
|
||||||
|
---
|
||||||
|
|
||||||
|
import { SimplePaneview } from '@site/src/components/simplePaneview';
|
||||||
|
import { CustomHeaderPaneview } from '@site/src/components/paneview/customHeader';
|
||||||
|
import { DragAndDropPaneview } from '@site/src/components/paneview/dragAndDrop';
|
||||||
|
import { SideBySidePaneview } from '@site/src/components/paneview/sideBySide';
|
||||||
|
import Link from '@docusaurus/Link';
|
||||||
|
|
||||||
|
# Paneview
|
||||||
|
|
||||||
|
A paneview is a collapsed collection of vertically stacked panels and panel headers.
|
||||||
|
The panel header will always remain visible however the panel will only be visible when the panel is expanded.
|
||||||
|
|
||||||
|
:::info
|
||||||
|
|
||||||
|
Paneview panels can be re-ordered by dragging and dropping the panel headers.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '400px',
|
||||||
|
backgroundColor: 'rgb(30,30,30)',
|
||||||
|
color: 'white',
|
||||||
|
margin: '20px 0px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SimplePaneview />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
```tsx title="Simple Paneview example"
|
||||||
|
import {
|
||||||
|
IPaneviewPanelProps,
|
||||||
|
PaneviewReact,
|
||||||
|
PaneviewReadyEvent,
|
||||||
|
} from 'dockview';
|
||||||
|
|
||||||
|
const components = {
|
||||||
|
default: (props: IPaneviewPanelProps<{ title: string }>) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: '10px',
|
||||||
|
height: '100%',
|
||||||
|
backgroundColor: 'rgb(60,60,60)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.params.title}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
SimplePaneview = () => {
|
||||||
|
const onReady = (event: PaneviewReadyEvent) => {
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_1',
|
||||||
|
component: 'default',
|
||||||
|
params: {
|
||||||
|
title: 'Panel 1',
|
||||||
|
},
|
||||||
|
title: 'Panel 1',
|
||||||
|
});
|
||||||
|
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_2',
|
||||||
|
component: 'default',
|
||||||
|
params: {
|
||||||
|
title: 'Panel 2',
|
||||||
|
},
|
||||||
|
title: 'Panel 2',
|
||||||
|
});
|
||||||
|
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_3',
|
||||||
|
component: 'default',
|
||||||
|
params: {
|
||||||
|
title: 'Panel 3',
|
||||||
|
},
|
||||||
|
title: 'Panel 3',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PaneviewReact
|
||||||
|
components={components}
|
||||||
|
headerComponents={headerComponents}
|
||||||
|
onReady={onReady}
|
||||||
|
className="dockview-theme-abyss"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## PaneviewReact Component
|
||||||
|
|
||||||
|
You can create a Paneview through the use of the `ReactPaneview` component.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { ReactPaneview } from 'dockview';
|
||||||
|
```
|
||||||
|
|
||||||
|
| Property | Type | Optional | Default | Description |
|
||||||
|
| ------------------- | ------------------------------------ | -------- | ------- | -------------------------------------------------------- |
|
||||||
|
| onReady | (event: SplitviewReadyEvent) => void | No | | |
|
||||||
|
| components | object | No | | |
|
||||||
|
| headerComponents | object | Yes | | |
|
||||||
|
| className | string | Yes | '' | |
|
||||||
|
| disableAutoResizing | boolean | Yes | false | <Link to="../basics/#auto-resizing">Auto Resizing</Link> |
|
||||||
|
| disableDnd | boolean | Yes | false | |
|
||||||
|
| onDidDrop | Event | Yes | | |
|
||||||
|
|
||||||
|
## Paneview API
|
||||||
|
|
||||||
|
The Paneview API is exposed both at the `onReady` event and on each panel through `props.containerApi`.
|
||||||
|
Through this API you can control general features of the component and access all added panels.
|
||||||
|
|
||||||
|
```tsx title="Paneview API via Panel component"
|
||||||
|
const MyComponent = (props: IGridviewPanelProps<{ title: string }>) => {
|
||||||
|
// props.containerApi...
|
||||||
|
|
||||||
|
return <div>{`My first panel has the title: ${props.params.title}`}</div>;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
```tsx title="Paneview API via the onReady callback"
|
||||||
|
const onReady = (event: GridviewReadyEvent) => {
|
||||||
|
// event.api...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
| Property | Type | Description |
|
||||||
|
| ------------------- | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
||||||
|
| height | `number` | Component pixel height |
|
||||||
|
| width | `number` | Component pixel width |
|
||||||
|
| minimumSize | `number` | The sum of the `minimumSize` property for each panel |
|
||||||
|
| maximumSize | `number` | The sum of the `maximumSize` property for each panel |
|
||||||
|
| length | `number` | Number of panels |
|
||||||
|
| panels | `IPaneviewPanel[]` | All panels |
|
||||||
|
| | | |
|
||||||
|
| onDidLayoutChange | `Event<void>` | Fires on layout change |
|
||||||
|
| onDidLayoutFromJSON | `Event<void>` | Fires of layout change caused by a fromJSON deserialization call |
|
||||||
|
| onDidAddView | `Event<IPaneviewPanel>` | Fires when a view is added |
|
||||||
|
| onDidRemoveView | `Event<IPaneviewPanel>` | Fires when a view is removed |
|
||||||
|
| onDidDrop | `Event<PaneviewDropEvent` | Fires on an external drop event (See <Link to="./paneview/#drag-and-drop">Drag and Drop</Link>) |
|
||||||
|
| | | |
|
||||||
|
| addPanel | `addPanel(options: AddPaneviewComponentOptions): IPaneviewPanel` | |
|
||||||
|
| removePanel | `(panel: IPaneviewPanel): void` | |
|
||||||
|
| movePanel | `(from: number, to: number): void` | |
|
||||||
|
| getPanel | `(id:string): IPaneviewPanel \| undefined` | |
|
||||||
|
| | | |
|
||||||
|
| focus | `(): void` | Focus the active panel, if exists |
|
||||||
|
| layout | `(width: number, height:number): void` | See <Link to="../basics/#auto-resizing">Auto Resizing</Link> |
|
||||||
|
| fromJSON | `(data: SerializedPaneview): void` | <Link to="../basics/#serialization">Serialization</Link> |
|
||||||
|
| toJSON | `(): SerializedPaneview` | <Link to="../basics/#serialization">Serialization</Link> |
|
||||||
|
| clear | `(): void` | Clears the current layout |
|
||||||
|
|
||||||
|
## Paneview Panel API
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const MyComponent = (props: IGridviewPanelProps<{ title: string }>) => {
|
||||||
|
// props.api...
|
||||||
|
|
||||||
|
return <div>{`My first panel has the title: ${props.params.title}`}</div>;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
| Property | Type | Description |
|
||||||
|
| ---------------------- | ----------------------------------------------------------- | ---------------- |
|
||||||
|
| id | `string` | Panel id |
|
||||||
|
| isFocused | `boolean` | Is panel focsed |
|
||||||
|
| isActive | `boolean` | Is panel active |
|
||||||
|
| isVisible | `boolean` | Is panel visible |
|
||||||
|
| width | `number` | Panel width |
|
||||||
|
| height | `number` | Panel height |
|
||||||
|
| | |
|
||||||
|
| onDidDimensionsChange | `Event<PanelDimensionChangeEvent>` | |
|
||||||
|
| onDidFocusChange | `Event<FocusEvent>` | |
|
||||||
|
| onDidVisibilityChange | `Event<VisibilityEvent>` | |
|
||||||
|
| onDidActiveChange | `Event<ActiveEvent>` | |
|
||||||
|
| onDidConstraintsChange | `onDidConstraintsChange: Event<PanelConstraintChangeEvent>` | |
|
||||||
|
| | |
|
||||||
|
| setVisible | `(isVisible: boolean): void` | |
|
||||||
|
| setActive | `(): void` | |
|
||||||
|
| setConstraints | `(value: PanelConstraintChangeEvent2): void;` | |
|
||||||
|
| setSize | `(event: SizeEvent): void` | |
|
||||||
|
|
||||||
|
## Advanced Features
|
||||||
|
|
||||||
|
### Custom Header
|
||||||
|
|
||||||
|
You can provide a custom component to render an alternative header.
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '400px',
|
||||||
|
backgroundColor: 'rgb(30,30,30)',
|
||||||
|
color: 'white',
|
||||||
|
margin: '20px 0px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CustomHeaderPaneview />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
You can provide a `headerComponent` option when creating a panel to tell the library to use a custom header component.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const onReady = (event: PaneviewReadyEvent) => {
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_1',
|
||||||
|
component: 'default',
|
||||||
|
headerComponent: 'myHeaderComponent',
|
||||||
|
params: {
|
||||||
|
valueA: 'A',
|
||||||
|
},
|
||||||
|
title: 'Panel 1',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
This header must be defined in the collection of components provided to the `headerComponents` props for `ReactPaneivew`
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { IPaneviewPanelProps } from 'dockview';
|
||||||
|
|
||||||
|
const MyHeaderComponent = (props: IPaneviewPanelProps<{ title: string }>) => {
|
||||||
|
const [expanded, setExpanded] = React.useState<boolean>(
|
||||||
|
props.api.isExpanded
|
||||||
|
);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const disposable = props.api.onDidExpansionChange((event) => {
|
||||||
|
setExpanded(event.isExpanded);
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
disposable.dispose();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onClick = () => {
|
||||||
|
props.api.setExpanded(!expanded);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: '10px',
|
||||||
|
height: '100%',
|
||||||
|
backgroundColor: 'rgb(60,60,60)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
onClick={onClick}
|
||||||
|
className={expanded ? 'expanded' : 'collapsed'}
|
||||||
|
/>
|
||||||
|
<span>{props.params.title}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const headerComponents = { myHeaderComponent: MyHeaderComponent };
|
||||||
|
```
|
||||||
|
|
||||||
|
### Drag And Drop
|
||||||
|
|
||||||
|
If you provide the `PaneviewReact` component with the prop `onDidDrop` you will be able to interact with custom drop events.
|
||||||
|
|
||||||
|
<DragAndDropPaneview />
|
||||||
|
|
||||||
|
### Interactions
|
||||||
|
|
||||||
|
You can safely create multiple paneview instances within one page. They will not interact with each other by default.
|
||||||
|
|
||||||
|
If you wish to interact with the drop event from one paneview instance in another paneview instance you can implement the `showDndOverlay` and `onDidDrop` props on `PaneviewReact`.
|
||||||
|
|
||||||
|
As an example see how dragging a header from one control to another will only trigger an interactable event for the developer if the checkbox is enabled.
|
||||||
|
|
||||||
|
<SideBySidePaneview />
|
246
packages/docs/versioned_docs/version-1.5.0/components/splitview.mdx
vendored
Normal file
246
packages/docs/versioned_docs/version-1.5.0/components/splitview.mdx
vendored
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
---
|
||||||
|
description: Splitview Documentation
|
||||||
|
---
|
||||||
|
|
||||||
|
import { SimpleSplitview } from '@site/src/components/simpleSplitview';
|
||||||
|
import { SplitviewExample1 } from '@site/src/components/splitview/active';
|
||||||
|
import Link from '@docusaurus/Link';
|
||||||
|
|
||||||
|
# Splitview
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
A Splitview is a collection of resizable horizontally or vertically stacked panels.
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '100px',
|
||||||
|
backgroundColor: 'rgb(30,30,30)',
|
||||||
|
color: 'white',
|
||||||
|
margin: '20px 0px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SimpleSplitview />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
```tsx title="Simple Splitview example"
|
||||||
|
import {
|
||||||
|
ISplitviewPanelProps,
|
||||||
|
Orientation,
|
||||||
|
SplitviewReact,
|
||||||
|
SplitviewReadyEvent,
|
||||||
|
} from 'dockview';
|
||||||
|
|
||||||
|
const components = {
|
||||||
|
default: (props: ISplitviewPanelProps<{ title: string }>) => {
|
||||||
|
return <div style={{ padding: '20px' }}>{props.params.title}</div>;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SimpleSplitview = () => {
|
||||||
|
const onReady = (event: SplitviewReadyEvent) => {
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_1',
|
||||||
|
component: 'default',
|
||||||
|
params: {
|
||||||
|
title: 'Panel 1',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_2',
|
||||||
|
component: 'default',
|
||||||
|
params: {
|
||||||
|
title: 'Panel 2',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_3',
|
||||||
|
component: 'default',
|
||||||
|
params: {
|
||||||
|
title: 'Panel 3',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SplitviewReact
|
||||||
|
components={components}
|
||||||
|
onReady={onReady}
|
||||||
|
orientation={Orientation.HORIZONTAL}
|
||||||
|
className="dockview-theme-abyss"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## SplitviewReact Component
|
||||||
|
|
||||||
|
You can create a Splitview through the use of the `ReactSplitview` component.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { ReactSplitview } from 'dockview';
|
||||||
|
```
|
||||||
|
|
||||||
|
Using the `onReady` prop you can access to the component `api` and add panels either through deserialization or the individual addition of panels.
|
||||||
|
|
||||||
|
| Property | Type | Optional | Default | Description |
|
||||||
|
| ------------------- | -------------------------------------- | -------- | ------------------------ | ------------------------------------------------------------------------ |
|
||||||
|
| onReady | `(event: SplitviewReadyEvent) => void` | No | | Function |
|
||||||
|
| components | `Record<string, ISplitviewPanelProps>` | No | | Panel renderers |
|
||||||
|
| orientation | `Orientation` | Yes | `Orientation.HORIZONTAL` | Orientation of the Splitview |
|
||||||
|
| proportionalLayout | `boolean` | Yes | `true` | See <Link to="../basics/#proportional-layout">Proportional layout</Link> |
|
||||||
|
| hideBorders | `boolean` | Yes | `false` | Hide the borders between panels |
|
||||||
|
| className | `string` | Yes | `''` | Attaches a classname |
|
||||||
|
| disableAutoResizing | `boolean` | Yes | `false` | See <Link to="../basics/#auto-resizing">Auto Resizing</Link> |
|
||||||
|
|
||||||
|
## Splitview API
|
||||||
|
|
||||||
|
The Splitview API is exposed both at the `onReady` event and on each panel through `props.containerApi`.
|
||||||
|
Through this API you can control general features of the component and access all added panels.
|
||||||
|
|
||||||
|
```tsx title="Splitview API via Panel component"
|
||||||
|
const MyComponent = (props: ISplitviewPanelProps<{ title: string }>) => {
|
||||||
|
// props.containerApi...
|
||||||
|
|
||||||
|
return <div>{`My first panel has the title: ${props.params.title}`}</div>;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
```tsx title="Splitview API via the onReady callback"
|
||||||
|
const onReady = (event: SplitviewReadyEvent) => {
|
||||||
|
// event.api...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
| Property | Type | Description |
|
||||||
|
| ------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------- |
|
||||||
|
| height | `number` | Component pixel height |
|
||||||
|
| width | `number` | Component pixel width |
|
||||||
|
| minimumSize | `number` | The sum of the `minimumSize` property for each panel |
|
||||||
|
| maximumSize | `number` | The sum of the `maximumSize` property for each panel |
|
||||||
|
| length | `number` | Number of panels |
|
||||||
|
| panels | `ISplitviewPanel[]` | All panels |
|
||||||
|
| | | |
|
||||||
|
| onDidLayoutChange | `Event<void>` | Fires on layout change |
|
||||||
|
| onDidLayoutFromJSON | `Event<void>` | Fires of layout change caused by a fromJSON deserialization call |
|
||||||
|
| onDidAddView | `Event<IView>` | Fires when a view is added |
|
||||||
|
| onDidRemoveView | `Event<IView>` | Fires when a view is removed |
|
||||||
|
| | | |
|
||||||
|
| addPanel | `addPanel(options: AddSplitviewComponentOptions): ISplitviewPanel` | |
|
||||||
|
| removePanel | `(panel: ISplitviewPanel, sizing?: Sizing): void` | |
|
||||||
|
| getPanel | `(id:string): ISplitviewPanel \| undefined` | |
|
||||||
|
| movePanel | `(from: number, to: number): void` | |
|
||||||
|
| | |
|
||||||
|
| updateOptions | `(options: SplitviewComponentUpdateOptions): void` | |
|
||||||
|
| focus | `(): void` | Focus the active panel, if exists |
|
||||||
|
| layout | `(width: number, height:number): void` | See <Link to="../basics/#auto-resizing">Auto Resizing</Link> |
|
||||||
|
| fromJSON | `(data: SerializedSplitview): void` | <Link to="../basics/#serialization">Serialization</Link> |
|
||||||
|
| toJSON | `(): SerializedSplitview` | <Link to="../basics/#serialization">Serialization</Link> |
|
||||||
|
| clear | `(): void` | Clears the current layout |
|
||||||
|
|
||||||
|
## Splitview Panel API
|
||||||
|
|
||||||
|
The Splitview panel API is exposed on each panel containing actions and variables specific to that panel.
|
||||||
|
|
||||||
|
```tsx title="Splitview panel API via Panel component"
|
||||||
|
const MyComponent = (props: ISplitviewPanelProps<{ title: string }>) => {
|
||||||
|
// props.api...
|
||||||
|
|
||||||
|
return <div>{`My first panel has the title: ${props.params.title}`}</div>;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
| Property | Type | Description |
|
||||||
|
| ---------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| id | `string` | Panel id |
|
||||||
|
| isFocused | `boolean` | Is panel focsed |
|
||||||
|
| isActive | `boolean` | Is panel active |
|
||||||
|
| isVisible | `boolean` | Is panel visible |
|
||||||
|
| width | `number` | Panel width |
|
||||||
|
| height | `number` | Panel height |
|
||||||
|
| | | |
|
||||||
|
| onDidDimensionsChange | `Event<PanelDimensionChangeEvent>` | Fires when panel dimensions change |
|
||||||
|
| onDidFocusChange | `Event<FocusEvent>` | Fire when panel is focused and blurred |
|
||||||
|
| onDidVisibilityChange | `Event<VisibilityEvent>` | Fires when the panels visiblity property is changed (see <Link to="./splitview/#visibility">Panel Visibility</Link>) |
|
||||||
|
| onDidActiveChange | `Event<ActiveEvent>` | Fires when the panels active property is changed (see <Link to="./splitview/#active">Active Panel</Link>) |
|
||||||
|
| onDidConstraintsChange | `onDidConstraintsChange: Event<PanelConstraintChangeEvent>` | Fires when the panels size contrainsts change (see <Link to="./splitview/#contraints">Panel Constraints</Link>) |
|
||||||
|
| | | |
|
||||||
|
| setVisible | `(isVisible: boolean): void` | |
|
||||||
|
| setActive | `(): void` | |
|
||||||
|
| | | |
|
||||||
|
| setConstraints | `(value: PanelConstraintChangeEvent2): void;` | |
|
||||||
|
| setSize | `(event: PanelSizeEvent): void` | |
|
||||||
|
|
||||||
|
## Advanced Features
|
||||||
|
|
||||||
|
Listed below are some functionalities avalaible through both the panel and component APIs. The live demo shows examples of these in real-time.
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '200px',
|
||||||
|
margin: '20px 0px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SplitviewExample1 />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
### Visibility
|
||||||
|
|
||||||
|
A panels visibility can be controlled and monitored through the following code.
|
||||||
|
A panel with visibility set to `false` will remain as a part of the components list of panels but will not be rendered.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const disposable = props.api.onDidVisibilityChange(({ isVisible }) => {
|
||||||
|
//
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
api.setVisible(true);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Active
|
||||||
|
|
||||||
|
Only one panel in the `splitview` can be the active panel at any one time.
|
||||||
|
Setting a panel as active will set all the others as inactive.
|
||||||
|
A focused panel is always the active panel but an active panel is not always focused.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const disposable = props.api.onDidActiveChange(({ isActive }) => {
|
||||||
|
//
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
api.setActive();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Contraints
|
||||||
|
|
||||||
|
When adding a panel you can specify pixel size contraints
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel_3',
|
||||||
|
component: 'default',
|
||||||
|
minimumSize: 100,
|
||||||
|
maximumSize: 1000,
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
These contraints can be updated throughout the lifecycle of the `splitview` using the panel API
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
props.api.onDidConstraintsChange(({ maximumSize, minimumSize }) => {
|
||||||
|
//
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
api.setConstraints({
|
||||||
|
maximumSize: 200,
|
||||||
|
minimumSize: 400,
|
||||||
|
});
|
||||||
|
```
|
25
packages/docs/versioned_docs/version-1.5.0/examples.mdx
vendored
Normal file
25
packages/docs/versioned_docs/version-1.5.0/examples.mdx
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 4
|
||||||
|
description: Dockview examples
|
||||||
|
---
|
||||||
|
|
||||||
|
import { SimpleSplitview } from '@site/src/components/simpleSplitview';
|
||||||
|
import { SimpleGridview } from '@site/src/components/simpleGridview';
|
||||||
|
import { SimplePaneview } from '@site/src/components/simplePaneview';
|
||||||
|
import { SimpleDockview } from '@site/src/components/simpleDockview';
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
|
||||||
|
<iframe
|
||||||
|
src="https://codesandbox.io/embed/dockview-template-mdc9f7?fontsize=14&hidenavigation=1&theme=dark"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '500px',
|
||||||
|
border: 0,
|
||||||
|
borderRaduis: '4px',
|
||||||
|
overflow: 'hidden',
|
||||||
|
}}
|
||||||
|
title="dockview-template"
|
||||||
|
allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
|
||||||
|
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
||||||
|
></iframe>
|
149
packages/docs/versioned_docs/version-1.5.0/index.mdx
vendored
Normal file
149
packages/docs/versioned_docs/version-1.5.0/index.mdx
vendored
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 0
|
||||||
|
description: A zero dependency layout manager built for React
|
||||||
|
---
|
||||||
|
|
||||||
|
import { SimpleSplitview } from '@site/src/components/simpleSplitview';
|
||||||
|
import { SimpleGridview } from '@site/src/components/simpleGridview';
|
||||||
|
import { SimplePaneview } from '@site/src/components/simplePaneview';
|
||||||
|
import { SimpleDockview } from '@site/src/components/simpleDockview';
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
**dockview** is a zero dependency layout manager that supports tab, grids and splitviews.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Themable and customizable
|
||||||
|
- Support for the serialization and deserialization of layouts
|
||||||
|
- Drag and drop support
|
||||||
|
|
||||||
|
## Quick start
|
||||||
|
|
||||||
|
`dockview` has a peer dependency on `react >= 16.8.0` and `react-dom >= 16.8.0`. To install `dockview` you can run:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npm install dockview
|
||||||
|
```
|
||||||
|
|
||||||
|
You must also import the dockview stylesheet found under [`dockview/dict/styles/dockview.css`](https://unpkg.com/browse/dockview@latest/dist/styles/dockview.css),
|
||||||
|
depending on your solution this might be:
|
||||||
|
|
||||||
|
```css
|
||||||
|
@import './node_modules/dockview/dist/styles/dockview.css';
|
||||||
|
```
|
||||||
|
|
||||||
|
A dark and light theme are provided, one of these classes (or a custom theme) must be attached at any point above your components in the HTML tree. To cover the entire web page you might attach the class to the `body` component:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<body classname="dockview-theme-abyss">
|
||||||
|
...
|
||||||
|
</body>
|
||||||
|
<body classname="dockview-theme-light">
|
||||||
|
...
|
||||||
|
</body>
|
||||||
|
```
|
||||||
|
|
||||||
|
There are 4 components you may want to use:
|
||||||
|
|
||||||
|
Splitview
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '100px',
|
||||||
|
backgroundColor: 'rgb(30,30,30)',
|
||||||
|
color: 'white',
|
||||||
|
margin: '20px 0px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SimpleSplitview />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '300px',
|
||||||
|
backgroundColor: 'rgb(30,30,30)',
|
||||||
|
color: 'white',
|
||||||
|
margin: '20px 0px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SimpleGridview />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '300px',
|
||||||
|
backgroundColor: 'rgb(30,30,30)',
|
||||||
|
color: 'white',
|
||||||
|
margin: '20px 0px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SimplePaneview />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '300px',
|
||||||
|
backgroundColor: 'rgb(30,30,30)',
|
||||||
|
color: 'white',
|
||||||
|
margin: '20px 0px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SimpleDockview />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import {
|
||||||
|
DockviewReact,
|
||||||
|
DockviewReadyEvent,
|
||||||
|
PanelCollection,
|
||||||
|
IDockviewPanelProps,
|
||||||
|
IDockviewPanelHeaderProps,
|
||||||
|
} from 'dockview';
|
||||||
|
|
||||||
|
const components: PanelCollection<IDockviewPanelProps> = {
|
||||||
|
default: (props: IDockviewPanelProps<{ someProps: string }>) => {
|
||||||
|
return <div>{props.params.someProps}</div>;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const headers: PanelCollection<IDockviewPanelHeaderProps> = {
|
||||||
|
customTab: (props: IDockviewPanelHeaderProps) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<span>{props.api.title}</span>
|
||||||
|
<span onClick={() => props.api.close()}>{'[x]'}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const Component = () => {
|
||||||
|
const onReady = (event: DockviewReadyEvent) => {
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel1',
|
||||||
|
component: 'default',
|
||||||
|
tabComponent: 'customTab', // optional custom header
|
||||||
|
params: {
|
||||||
|
someProps: 'Hello',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
event.api.addPanel({
|
||||||
|
id: 'panel2',
|
||||||
|
component: 'default',
|
||||||
|
params: {
|
||||||
|
someProps: 'World',
|
||||||
|
},
|
||||||
|
position: { referencePanel: 'panel1', direction: 'below' },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DockviewReact
|
||||||
|
components={components}
|
||||||
|
tabComponents={headers} // optional headers renderer
|
||||||
|
onReady={onReady}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
```
|
89
packages/docs/versioned_docs/version-1.5.0/theme.mdx
vendored
Normal file
89
packages/docs/versioned_docs/version-1.5.0/theme.mdx
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 3
|
||||||
|
description: Theming Dockview Components
|
||||||
|
---
|
||||||
|
|
||||||
|
import { CustomCSSDockview } from '@site/src/components/dockview/customCss';
|
||||||
|
|
||||||
|
# Theme
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
`dockview` requires some css to work correctly.
|
||||||
|
The css is exported as one file under [`dockview/dict/styles/dockview.css`](https://unpkg.com/browse/dockview@latest/dist/styles/dockview.css)
|
||||||
|
and depending can be imported
|
||||||
|
|
||||||
|
```css
|
||||||
|
@import './node_modules/dockview/dist/styles/dockview.css';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Provided themes
|
||||||
|
|
||||||
|
The following are provided as classes that you can attached to your components for themeing
|
||||||
|
|
||||||
|
- `.dockview-theme-light`
|
||||||
|
- `.dockview-theme-dark`
|
||||||
|
- `.dockview-theme-abyss`
|
||||||
|
|
||||||
|
## Customizing Theme
|
||||||
|
|
||||||
|
`dockview` supports theming through the use of css properties.
|
||||||
|
You can view the built-in themes at [`dockview/src/theme.scss`](https://github.com/mathuo/dockview/blob/master/packages/dockview/src/theme.scss)
|
||||||
|
and are free to build your own themes based on these css properties.
|
||||||
|
|
||||||
|
| CSS Property | Description |
|
||||||
|
| ---------------------------------------------------- | ----------- |
|
||||||
|
| --dv-paneview-active-outline-color | |
|
||||||
|
| --dv-tabs-and-actions-container-font-size | |
|
||||||
|
| --dv-tabs-and-actions-container-height | |
|
||||||
|
| --dv-tab-close-icon | |
|
||||||
|
| --dv-drag-over-background-color | |
|
||||||
|
| --dv-drag-over-border-color | |
|
||||||
|
| --dv-tabs-container-scrollbar-color | |
|
||||||
|
| | |
|
||||||
|
| --dv-group-view-background-color | |
|
||||||
|
| | |
|
||||||
|
| --dv-tabs-and-actions-container-background-color | |
|
||||||
|
| | |
|
||||||
|
| --dv-activegroup-visiblepanel-tab-background-color | |
|
||||||
|
| --dv-activegroup-hiddenpanel-tab-background-color | |
|
||||||
|
| --dv-inactivegroup-visiblepanel-tab-background-color | |
|
||||||
|
| --dv-inactivegroup-hiddenpanel-tab-background-color | |
|
||||||
|
| --dv-tab-divider-color | |
|
||||||
|
| | |
|
||||||
|
| --dv-activegroup-visiblepanel-tab-color | |
|
||||||
|
| --dv-activegroup-hiddenpanel-tab-color | |
|
||||||
|
| --dv-inactivegroup-visiblepanel-tab-color | |
|
||||||
|
| --dv-inactivegroup-hiddenpanel-tab-color | |
|
||||||
|
| | |
|
||||||
|
| --dv-separator-border | |
|
||||||
|
| --dv-paneview-header-border-color | |
|
||||||
|
|
||||||
|
You can further customise the theme through adjusting class properties but this is up you.
|
||||||
|
As an example if you wanted to add a bottom border to the tab container for an active group in the `DockviewReact` component you could write:
|
||||||
|
|
||||||
|
```css
|
||||||
|
.groupview {
|
||||||
|
&.active-group {
|
||||||
|
> .tabs-and-actions-container {
|
||||||
|
border-bottom: 2px solid var(--dv-activegroup-visiblepanel-tab-background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.inactive-group {
|
||||||
|
> .tabs-and-actions-container {
|
||||||
|
border-bottom: 2px solid var(--dv-inactivegroup-visiblepanel-tab-background-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '300px',
|
||||||
|
backgroundColor: 'rgb(30,30,30)',
|
||||||
|
color: 'white',
|
||||||
|
margin: '20px 0px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CustomCSSDockview />
|
||||||
|
</div>
|
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"tutorialSidebar": [
|
||||||
|
{
|
||||||
|
"type": "autogenerated",
|
||||||
|
"dirName": "."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
[
|
[
|
||||||
|
"1.5.0",
|
||||||
"1.4.3"
|
"1.4.3"
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user