Merge pull request #125 from mathuo/100-docs

chore: improve docs!
This commit is contained in:
mathuo 2022-05-29 16:49:59 +01:00 committed by GitHub
commit f563ae4fe4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 436 additions and 96 deletions

View File

@ -15,7 +15,7 @@
##
Please see the website: https://mathuo.github.io/dockview/docs
Please see the website: https://dockview.dev
Want to inspect the latest deployment? Go to https://unpkg.com/browse/dockview@latest/

View File

@ -15,7 +15,7 @@
##
Please see the website: https://mathuo.github.io/dockview/docs
Please see the website: https://dockview.dev
Want to inspect the latest deployment? Go to https://unpkg.com/browse/dockview@latest/

View File

@ -1,7 +0,0 @@
{
"label": "API",
"position": 2,
"link": {
"type": "generated-index"
}
}

View File

@ -0,0 +1,9 @@
{
"label": "Components",
"collapsible": true,
"collapsed": false,
"link": {
"type": "generated-index",
"title": "Components"
},
}

View File

@ -5,13 +5,14 @@ import {
} from '../../src/components/dockview/rendering';
import { DndDockview } from '../../src/components/dockview/dnd';
import { EventsDockview } from '../../src/components/dockview/events';
import { ContextMenuDockview } from '../../src/components/dockview/contextMenu';
import Link from '@docusaurus/Link';
# Dockview
## Introduction
Dockview is an abstraction built on top of [Gridviews](/docs/api/gridview) where each view is a tabbed container.
Dockview is an abstraction built on top of [Gridviews](/docs/api/gridview) where each view is a container of many tabbed panels.
<div
style={{
@ -24,16 +25,13 @@ Dockview is an abstraction built on top of [Gridviews](/docs/api/gridview) where
<SimpleDockview />
</div>
```tsx
const panel = event.api.addPanel(...);
const anotherPanel = event.api.getPanel('somePanelid');
```
You can access the panels associated group through the `panel.group` variable.
The group will always be defined and will change if a panel is moved into another group.
## DockviewReact Component
You can create a Dockview through the use of the `ReactDockview` component.
```tsx
import { ReactDockview } from 'dockview';
```
@ -53,7 +51,10 @@ import { ReactDockview } from 'dockview';
## Dockview API
```tsx
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...
@ -61,7 +62,7 @@ const MyComponent = (props: IDockviewPanelProps<{ title: string }>) => {
};
```
```tsx
```tsx title="Dockview API via the onReady callback"
const onReady = (event: DockviewReadyEvent) => {
// event.api...
};
@ -147,7 +148,7 @@ const MyComponent = (props: IDockviewPanelProps<{ title: string }>) => {
### 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.
You can still add groups to a locked panel programatically using the API.
```tsx
panel.group.locked = true;
@ -163,7 +164,15 @@ panel.group.header.hidden = true;
### Context Menu
import { ContextMenuDockview } from '../../src/components/dockview/contextMenu';
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 alternatively define a custom tab component for more granular control.
:::caution
The `onTabContextMenu` is intended to be removed in a future release to further simplify the library.
In the future you will be required to define a custom tab component to intercept the context menu events.
:::
<div
style={{

View File

@ -1,8 +1,21 @@
import { SimplePaneview } from '../../src/components/simplePaneview';
import { CustomHeaderPaneview } from '../../src/components/paneview/customHeader';
import { DragAndDropPaneview } from '../../src/components/paneview/dragAndDrop';
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
@ -16,8 +29,74 @@ import Link from '@docusaurus/Link';
<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-dark"
/>
);
};
```
## PaneviewReact Component
You can create a Paneview through the use of the `ReactPaneview` component.
```tsx
import { ReactPaneview } from 'dockview';
```
@ -34,7 +113,10 @@ import { ReactPaneview } from 'dockview';
## Paneview API
```tsx
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...
@ -42,7 +124,7 @@ const MyComponent = (props: IGridviewPanelProps<{ title: string }>) => {
};
```
```tsx
```tsx title="Paneview API via the onReady callback"
const onReady = (event: GridviewReadyEvent) => {
// event.api...
};
@ -74,7 +156,7 @@ const onReady = (event: GridviewReadyEvent) => {
| toJSON | `(): SerializedPaneview` | <Link to="/docs/basics/#serialization">Serialization</Link> |
| clear | `(): void` | Clears the current layout |
## Gridview Panel API
## Paneview Panel API
```tsx
const MyComponent = (props: IGridviewPanelProps<{ title: string }>) => {
@ -108,8 +190,20 @@ const MyComponent = (props: IGridviewPanelProps<{ title: string }>) => {
### Custom Header
The above example shows the default header and will render the `title` along with a small icon to indicate a collapsed or expanded state.
You can provide a custom header:
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) => {
@ -125,27 +219,12 @@ const onReady = (event: PaneviewReadyEvent) => {
};
```
The above example shows the default header and will render the `title` along with a small icon to indicate a collapsed or expanded state.
You can provide a custom header:
This header must be defined in the collection of components provided to the `headerComponents` props for `ReactPaneivew`
```tsx
const onReady = (event: PaneviewReadyEvent) => {
event.api.addPanel({
id: 'panel_1',
component: 'default',
headerComponent: 'myHeaderComponent',
params: {
valueA: 'A',
},
title: 'Panel 1',
});
};
```
import { IPaneviewPanelProps } from 'dockview';
You can define a header component and listen to the expanded state to update the component accordingly.
```tsx
const CustomHeader = (props: IPaneviewPanelProps) => {
const MyHeaderComponent = (props: IPaneviewPanelProps<{ title: string }>) => {
const [expanded, setExpanded] = React.useState<boolean>(
props.api.isExpanded
);
@ -165,7 +244,13 @@ const CustomHeader = (props: IPaneviewPanelProps) => {
};
return (
<div>
<div
style={{
padding: '10px',
height: '100%',
backgroundColor: 'rgb(60,60,60)',
}}
>
<a
onClick={onClick}
className={expanded ? 'expanded' : 'collapsed'}
@ -174,12 +259,12 @@ const CustomHeader = (props: IPaneviewPanelProps) => {
</div>
);
};
```
You should provide a value for the `headerComponents` React prop.
```tsx
const headerComponents = { myHeaderComponent: CustomHeader };
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 />

View File

@ -6,9 +6,7 @@ import Link from '@docusaurus/Link';
## Introduction
A Splitview is a collection resizable horizontally or vertically stacked panels.
The Splitview exposes a component level API through the `onReady` event and through the `props.containerApi` variable on the panel props.
A panel level API is exposed on each panel through it's props as `props.api`.
A Splitview is a collection of resizable horizontally or vertically stacked panels.
<div
style={{
@ -81,7 +79,7 @@ You can create a Splitview through the use of the `ReactSplitview` component.
import { ReactSplitview } from 'dockview';
```
Using the `onReady` prop you can access to the component `api` and add panels either through deserialization or indivial addition of panels.
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 |
| ------------------- | -------------------------------------- | -------- | ------------------------ | --------------------------------------------------------------------------- |
@ -96,6 +94,7 @@ Using the `onReady` prop you can access to the component `api` and add panels ei
## 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 }>) => {
@ -139,7 +138,7 @@ const onReady = (event: SplitviewReadyEvent) => {
## Splitview Panel API
The Splitview panel API is exposed on each panel and contains actions and variables specific to that panel.
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 }>) => {
@ -172,7 +171,7 @@ const MyComponent = (props: ISplitviewPanelProps<{ title: string }>) => {
## Advanced Features
Listed below are some functionality avalaible to you through both the panel and component APIs. The live demo shows examples of these in real-time.
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={{
@ -185,7 +184,7 @@ Listed below are some functionality avalaible to you through both the panel and
### Visibility
A panels visibility can be controlled and monitoring through the following code.
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

View File

@ -12,7 +12,7 @@ console.log(`isCI: ${process.env.CI}`);
const config = {
title: 'Dockview',
tagline: 'Zero dependency layout manager for React',
url: 'https://your-docusaurus-test-site.com',
url: 'https://dockview.dev',
baseUrl: process.env.CI ? `/` : '/',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
@ -87,6 +87,28 @@ const config = {
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
metadata: [
{
name: 'keywords',
content: [
'react',
'components',
'typescript',
'drag-and-drop',
'reactjs',
'layout',
'drag',
'drop',
'tabs',
'dock',
'docking',
'splitter',
'docking-library',
'layout-manager',
'docking-layout',
].join(' ,'),
},
],
navbar: {
title: 'Dockview',
logo: {

View File

@ -0,0 +1,28 @@
.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;
}
}
}

View File

@ -3,65 +3,48 @@ import {
DockviewReadyEvent,
IDockviewPanelHeaderProps,
IDockviewPanelProps,
TabContextMenuEvent,
} from 'dockview';
import * as React from 'react';
import './contextMenu.scss';
//
const components = {
default: (props: IDockviewPanelProps<{ title: string }>) => {
return <div style={{ padding: '20px' }}>{props.params.title}</div>;
},
};
const DefaultTab = (props: IDockviewPanelHeaderProps) => {
const [active, setActive] = React.useState<boolean>(props.api.isActive);
const [groupActive, setGroupActive] = React.useState<boolean>(
props.api.isGroupActive
const CustomTab = (
props: IDockviewPanelHeaderProps & React.DOMAttributes<HTMLDivElement>
) => {
const onClose = React.useCallback(
(event: React.MouseEvent<HTMLSpanElement>) => {
event.stopPropagation();
props.api.close();
},
[props.api]
);
React.useEffect(() => {
const disposable1 = props.api.onDidActiveChange((e) => {
setActive(e.isActive);
});
const disposable2 = props.containerApi.onDidActiveGroupChange((e) => {
setGroupActive(props.api.isGroupActive);
});
return () => {
disposable1.dispose();
disposable2.dispose();
};
const onClick = React.useCallback(() => {
props.api.setActive();
}, [props.api]);
return (
<div
style={{
display: 'flex',
padding: '0px 8px',
alignItems: 'center',
height: '100%',
}}
>
<span style={{ padding: '0px 8px', flexGrow: 1 }}>
{props.api.title}
</span>
<span
className=""
onClick={() => props.api.setActive()}
style={{
display: 'flex',
alignItems: 'center',
paddingRight: '8px',
}}
>
<div onClick={onClick} className="dockview-react-tab">
<span className="dockview-react-tab-title">{props.api.title}</span>
<span onClick={onClose} className="dockview-react-tab-action">
{'✕'}
</span>
</div>
);
};
const Test = (props: IDockviewPanelHeaderProps) => {
return <CustomTab {...props} />;
};
const tabComponents = {
default: DefaultTab,
default: CustomTab,
};
export const ContextMenuDockview = () => {
@ -104,12 +87,18 @@ export const ContextMenuDockview = () => {
});
};
const onContextMenu = (event: TabContextMenuEvent) => {
event.event.preventDefault();
alert(`Content appear event fired for panel ${event.panel.id}`);
};
return (
<DockviewReact
components={components}
tabComponents={tabComponents}
onReady={onReady}
className="dockview-theme-dark"
onTabContextMenu={onContextMenu}
/>
);
};

View File

@ -0,0 +1,104 @@
import {
IPaneviewPanelProps,
PaneviewReact,
PaneviewReadyEvent,
} from 'dockview';
import * as React from 'react';
const components = {
default: (props: IPaneviewPanelProps<{ title: string }>) => {
return (
<div
style={{
padding: '10px',
height: '100%',
backgroundColor: 'rgb(60,60,60)',
}}
>
{props.params.title}
</div>
);
},
};
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: '0px 8px',
height: '100%',
backgroundColor: 'rgb(60,60,60)',
}}
>
<span>{`Custom header for ${props.title}`}</span>
<button onClick={onClick}>
{expanded ? 'Collapse' : 'Expand'}
</button>
</div>
);
};
const headerComponents = {
myHeaderComponent: MyHeaderComponent,
};
export const CustomHeaderPaneview = () => {
const onReady = (event: PaneviewReadyEvent) => {
event.api.addPanel({
id: 'panel_1',
component: 'default',
headerComponent: 'myHeaderComponent',
params: {
title: 'Panel 1',
},
title: 'Panel 1',
});
event.api.addPanel({
id: 'panel_2',
component: 'default',
headerComponent: 'myHeaderComponent',
params: {
title: 'Panel 2',
},
title: 'Panel 2',
});
event.api.addPanel({
id: 'panel_3',
component: 'default',
headerComponent: 'myHeaderComponent',
params: {
title: 'Panel 3',
},
title: 'Panel 3',
});
};
return (
<PaneviewReact
components={components}
headerComponents={headerComponents}
onReady={onReady}
className="dockview-theme-dark"
/>
);
};

View File

@ -0,0 +1,102 @@
import {
IPaneviewPanelProps,
PaneviewDropEvent,
PaneviewReact,
PaneviewReadyEvent,
} from 'dockview';
import * as React from 'react';
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 DragAndDropPaneview = () => {
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 onDidDrop = (event: PaneviewDropEvent) => {
const index = event.api.panels.indexOf(event.panel);
event.api.addPanel({
id: 'panel_4',
component: 'default',
params: {
title: 'Panel 4',
},
title: 'Panel 4',
index,
});
};
return (
<div>
<div>
<div
style={{
backgroundColor: 'orange',
padding: '0px 8px',
borderRadius: '4px',
width: '100px',
cursor: 'pointer',
}}
draggable={true}
>
Drag me
</div>
</div>
<div
style={{
height: '300px',
backgroundColor: 'rgb(30,30,30)',
color: 'white',
margin: '20px 0px',
}}
>
<PaneviewReact
components={components}
onReady={onReady}
onDidDrop={onDidDrop}
className="dockview-theme-dark"
/>
</div>
</div>
);
};

View File

@ -31,8 +31,8 @@ export default function Home(): JSX.Element {
const { siteConfig } = useDocusaurusContext();
return (
<Layout
title={`Hello from ${siteConfig.title}`}
description="Description will go into a meta tag in <head />"
title={`${siteConfig.title}`}
description="A zero dependency layout mananger for React."
>
<HomepageHeader />
<main className="container">