From 03235172a83ef071cbc41caac111b9d401d071f9 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Wed, 4 Oct 2023 20:58:51 +0100 Subject: [PATCH] chore: docs --- .codesandbox/ci.json | 2 + .../docs/blog/2023-10-06-dockview-1.8.4.md | 33 +++ packages/docs/docs/components/dockview.mdx | 2 +- packages/docs/docs/components/gridview.mdx | 148 ++++++++++++ packages/docs/docs/theme.mdx | 5 + .../docs/sandboxes/demo-dockview/src/app.tsx | 34 +-- .../sandboxes/editor-gridview/package.json | 32 +++ .../editor-gridview/public/index.html | 44 ++++ .../sandboxes/editor-gridview/src/app.scss | 3 + .../sandboxes/editor-gridview/src/app.tsx | 213 ++++++++++++++++++ .../sandboxes/editor-gridview/src/index.tsx | 20 ++ .../sandboxes/editor-gridview/src/styles.css | 16 ++ .../sandboxes/editor-gridview/tsconfig.json | 18 ++ .../sandboxes/simple-gridview/src/app.scss | 3 + .../src/components/ui/codeSandboxButton.tsx | 7 +- packages/docs/src/components/ui/container.tsx | 7 +- 16 files changed, 555 insertions(+), 32 deletions(-) create mode 100644 packages/docs/blog/2023-10-06-dockview-1.8.4.md create mode 100644 packages/docs/sandboxes/editor-gridview/package.json create mode 100644 packages/docs/sandboxes/editor-gridview/public/index.html create mode 100644 packages/docs/sandboxes/editor-gridview/src/app.scss create mode 100644 packages/docs/sandboxes/editor-gridview/src/app.tsx create mode 100644 packages/docs/sandboxes/editor-gridview/src/index.tsx create mode 100644 packages/docs/sandboxes/editor-gridview/src/styles.css create mode 100644 packages/docs/sandboxes/editor-gridview/tsconfig.json create mode 100644 packages/docs/sandboxes/simple-gridview/src/app.scss diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json index d4a057c08..19e381168 100644 --- a/.codesandbox/ci.json +++ b/.codesandbox/ci.json @@ -9,6 +9,7 @@ "/packages/docs/sandboxes/demo-dockview", "/packages/docs/sandboxes/dnd-dockview", "/packages/docs/sandboxes/dockview-app", + "/packages/docs/sandboxes/editor-gridview", "/packages/docs/sandboxes/events-dockview", "/packages/docs/sandboxes/externaldnd-dockview", "/packages/docs/sandboxes/floatinggroup-dockview", @@ -26,6 +27,7 @@ "/packages/docs/sandboxes/resize-dockview", "/packages/docs/sandboxes/resizecontainer-dockview", "/packages/docs/sandboxes/simple-dockview", + "/packages/docs/sandboxes/simple-gridview", "/packages/docs/sandboxes/simple-paneview", "/packages/docs/sandboxes/tabheight-dockview", "/packages/docs/sandboxes/updatetitle-dockview", diff --git a/packages/docs/blog/2023-10-06-dockview-1.8.4.md b/packages/docs/blog/2023-10-06-dockview-1.8.4.md new file mode 100644 index 000000000..928b517b4 --- /dev/null +++ b/packages/docs/blog/2023-10-06-dockview-1.8.4.md @@ -0,0 +1,33 @@ +--- +slug: dockview-1.8.4-release +title: Dockview 1.8.4 +tags: [release] +--- + +# Release Notes + +Please reference to docs @ [dockview.dev](https://dockview.dev). + +## 🚀 Features + +- Optional header actions before tabs list [#338](https://github.com/mathuo/dockview/issues/338) + +## 🛠 Miscs + +- Bug: Recover from corrupted layouts gracefully [#341](https://github.com/mathuo/dockview/issues/341) + +- Bug: Fix floating group resizing within nested tabs [#344](https://github.com/mathuo/dockview/issues/344) + +- Bug: Progmatic resizing priority [#350](https://github.com/mathuo/dockview/issues/350) + +- Bug: Incorrect disposal of deeply nested gridview [#356](https://github.com/mathuo/dockview/issues/356) + +- Splitview separator stlye restored on deserialize step [#358](https://github.com/mathuo/dockview/issues/358) + +- Docs: Additional Docs [#347](https://github.com/mathuo/dockview/issues/347) + +- Docs: Additional Docs [#336](https://github.com/mathuo/dockview/issues/336) + +- Docs: Additional Docs [#352](https://github.com/mathuo/dockview/issues/352) + +## 🔥 Breaking changes diff --git a/packages/docs/docs/components/dockview.mdx b/packages/docs/docs/components/dockview.mdx index 72a48bd56..9c9ac1ed9 100644 --- a/packages/docs/docs/components/dockview.mdx +++ b/packages/docs/docs/components/dockview.mdx @@ -426,7 +426,7 @@ Finally `addPanel` accepts a `position` object which tells dockview where to pla - This object accepts a `direction` property which dictates where, relative to the provided reference the new panel will be placed. -> If neither a `referencePanel` or `referenceGroup` then the provided `direction` will be treated as absolute. +> If neither a `referencePanel` or `referenceGroup` is provided then the `direction` will be treated as absolute. > If no `direction` is provided the library will place the new panel in a pre-determined position. diff --git a/packages/docs/docs/components/gridview.mdx b/packages/docs/docs/components/gridview.mdx index 218fe1822..5d61ed21a 100644 --- a/packages/docs/docs/components/gridview.mdx +++ b/packages/docs/docs/components/gridview.mdx @@ -4,6 +4,7 @@ description: Gridview Documentation import { MultiFrameworkContainer } from '@site/src/components/ui/container'; import SimpleGridview from '@site/sandboxes/simple-gridview/src/app'; +import EditorGridview from '@site/sandboxes/editor-gridview/src/app'; // import SimpleGridview from '@site/sandboxes/simple-gridview/src/app'; import { EventsGridview } from '@site/src/components/gridview/events'; // import IDEExample from '@site/sandboxes/ide-example/src/app'; @@ -61,6 +62,144 @@ const MyComponent = (props: IGridviewPanelProps<{ title: string }>) => { +## Resizing + +### Panel Resizing + +You can set the size of a panel using `props.api.setSize(...)`. + +```tsx +// it's mandatory to provide either a height or a width, providing both is optional +props.api.setSize({ + height: 100, + width: 200, +}); +``` + +You can update any constraints on the panel. All parameters are optional. + +```tsx +props.api.setConstraints({ + minimumHeight: 100, + maximumHeight: 1000 + minimumWidth: 100, + maximumWidth: 1000 +}); +``` + +You can hide a panel by setting it's visibility to `false`. Hidden panels retain their size +at the point of being hidden, if made visible again they will try to resize to the remembered size. + +```tsx +props.api.setVisible(false); +``` + +## Panels + +### Add Panel + +Using the gridview API you can access the `addPanel` method which returns an instance of the created panel. +The minimum method signature is: + +```ts +const panel = api.addPanel({ + id: 'my_unique_panel_id', + component: 'my_component', +}); +``` + +where `id` is the unique id of the panel and `component` is the implenentation which +will be used to render the panel. You will have registered this using the `components` prop of the `GridviewReactComponent` component. + +You can pass bounding constraints to limit the size of the panel. + +```ts +const panel = api.addPanel({ + id: 'my_unique_panel_id', + component: 'my_component', + minimumHeight: 100, + maximumHeight: 1000, + minimumWidth: 100, + maximumWidth: 1000, +}); +``` + +You can pass a `snap` parameter which will hide the panel when an attempt is made to move it beyond a minimum width or height if one exists. + +```ts +const panel = api.addPanel({ + id: 'my_unique_panel_id', + component: 'my_component', + minimumHeight: 100, + snap: true, +}); +``` + +You can pass a `priority` parameter which will keep the panel a certain priority when being resized. This is useful when you know you want this +panel to always take the first available or last available space. The default is `LayoutPriority.Normal` which defers space allocations to the libraries discression. + +```ts +const panel = api.addPanel({ + id: 'my_unique_panel_id', + component: 'my_component', + minimumHeight: 100, + priority: LayoutPriority.High, +}); +``` + +You can pass properties to the panel using the `params` key. +You can update these properties through the panels `api` object and its `updateParameters` method. + +```ts +const panel = api.addPanel({ + id: 'my_unique_panel_id', + component: 'my_component', + params: { + myCustomKey: 'my_custom_value', + }, +}); +``` + +```tsx +panel.api.updateParameters({ + myCustomKey: 'my_custom_value', + myOtherCustomKey: 'my_other_custom_key', +}); +``` + +> Note `updateParameters` does not accept partial parameter updates, you should call it with the entire set of parameters +> you want the panel to receive. + +Finally `addPanel` accepts a `position` object which tells dockview where to place the panel. + +- This object accepts a `referencePanel` which can be the associated id as a string + or the panel object reference. +- This object accepts a `direction` property which dictates where, + relative to the provided reference the new panel will be placed. + +> If a `referencePanel` is not passed then the `direction` will be treated as absolute. + +> If no `direction` is provided the library will place the new panel in a pre-determined position. + +```ts +const panel = api.addPanel({ + id: 'panel_1', + component: 'default', +}); + +const panel2 = api.addPanel({ + id: 'panel_2', + component: 'default', + position: { + referencePanel: panel1, + direction: 'right', + }, +}); +``` + +> Note `updateParameters` does not accept partial parameter updates, you should call it with the entire set of parameters +> you want the panel to receive. + ## Theme As well as importing the `dockview` stylesheet you must provide a class-based theme somewhere in your application. For example. @@ -85,3 +224,12 @@ You can find more details on theming here. `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. + +## Complex Example + + diff --git a/packages/docs/docs/theme.mdx b/packages/docs/docs/theme.mdx index 49a8c23ef..a3d119323 100644 --- a/packages/docs/docs/theme.mdx +++ b/packages/docs/docs/theme.mdx @@ -60,6 +60,11 @@ and are free to build your own themes based on these css properties. | | | | --dv-separator-border | | | --dv-paneview-header-border-color | | +| | | +| --dv-icon-hover-background-color | | +| --dv-floating-box-shadow | | +| --dv-active-sash-color | | +| --dv-background-color | | You can further customise the theme through adjusting class properties but this is up you. For example if you wanted to add a bottom border to the tab container for an active group in the `DockviewReact` component you could write: diff --git a/packages/docs/sandboxes/demo-dockview/src/app.tsx b/packages/docs/sandboxes/demo-dockview/src/app.tsx index 0e5b2ff96..43a1c779f 100644 --- a/packages/docs/sandboxes/demo-dockview/src/app.tsx +++ b/packages/docs/sandboxes/demo-dockview/src/app.tsx @@ -219,11 +219,13 @@ const DockviewDemo = (props: { theme?: string }) => { id: 'panel_2', component: 'default', title: 'Panel 2', + position: { referencePanel: 'panel_1', direction: 'right' }, }); event.api.addPanel({ id: 'panel_3', component: 'default', title: 'Panel 3', + position: { referencePanel: 'panel_2', direction: 'below' }, }); event.api.addPanel({ id: 'panel_4', @@ -235,42 +237,18 @@ const DockviewDemo = (props: { theme?: string }) => { id: 'panel_5', component: 'default', title: 'Panel 5', - position: { referencePanel: 'panel_4', direction: 'within' }, + position: { referencePanel: 'panel_3', direction: 'below' }, }); event.api.addPanel({ id: 'panel_6', component: 'default', title: 'Panel 6', - position: { referencePanel: 'panel_4', direction: 'below' }, - }); - 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.addPanel({ - id: 'panel_9', - component: 'default', - title: 'Panel 9', - floating: { width: 450, height: 250 }, - }); - - event.api.addPanel({ - id: 'panel_10', - component: 'default', - title: 'Panel 10', - position: { referencePanel: 'panel_9' }, + position: { referencePanel: 'panel_3', direction: 'right' }, }); event.api.getPanel('panel_1')!.api.setActive(); + + console.log(event.api.toJSON()); }; return ( diff --git a/packages/docs/sandboxes/editor-gridview/package.json b/packages/docs/sandboxes/editor-gridview/package.json new file mode 100644 index 000000000..226aa5c77 --- /dev/null +++ b/packages/docs/sandboxes/editor-gridview/package.json @@ -0,0 +1,32 @@ +{ + "name": "editor-gridview", + "description": "", + "keywords": [ + "dockview" + ], + "version": "1.0.0", + "main": "src/index.tsx", + "dependencies": { + "dockview": "*", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "typescript": "^4.9.5", + "react-scripts": "*" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test --env=jsdom", + "eject": "react-scripts eject" + }, + "browserslist": [ + ">0.2%", + "not dead", + "not ie <= 11", + "not op_mini all" + ] +} \ No newline at end of file diff --git a/packages/docs/sandboxes/editor-gridview/public/index.html b/packages/docs/sandboxes/editor-gridview/public/index.html new file mode 100644 index 000000000..1f8a52426 --- /dev/null +++ b/packages/docs/sandboxes/editor-gridview/public/index.html @@ -0,0 +1,44 @@ + + + + + + + + + + + + + React App + + + + +
+ + + + diff --git a/packages/docs/sandboxes/editor-gridview/src/app.scss b/packages/docs/sandboxes/editor-gridview/src/app.scss new file mode 100644 index 000000000..a708b2796 --- /dev/null +++ b/packages/docs/sandboxes/editor-gridview/src/app.scss @@ -0,0 +1,3 @@ +.simple-gridview-example { + --dv-active-sash-color: #007acc; +} diff --git a/packages/docs/sandboxes/editor-gridview/src/app.tsx b/packages/docs/sandboxes/editor-gridview/src/app.tsx new file mode 100644 index 000000000..25678292e --- /dev/null +++ b/packages/docs/sandboxes/editor-gridview/src/app.tsx @@ -0,0 +1,213 @@ +import { + GridviewApi, + GridviewReact, + GridviewReadyEvent, + IGridviewPanelProps, + LayoutPriority, + Orientation, + SerializedGridviewComponent, +} from 'dockview'; +import * as React from 'react'; +import './app.scss'; + +const components = { + default: (props: IGridviewPanelProps<{ title: string }>) => { + return ( +
+ {props.params.title} +
+ ); + }, + header: (props: IGridviewPanelProps) => { + return ( +
+ ); + }, + footer: (props: IGridviewPanelProps) => { + return ( +
+ ); + }, + sidebar: (props: IGridviewPanelProps) => { + return ( +
+ ); + }, + 'left-expander': (props: IGridviewPanelProps) => { + return ( +
+ ); + }, + 'right-expander': (props: IGridviewPanelProps) => { + return ( +
+ ); + }, + main: (props: IGridviewPanelProps) => { + return ( +
+
{'This entire mockup is built using a gridview.'}
+ +
{`Press 'Ctrl+B' to toggle the left sidebar and 'Ctrl+Alt+B' to toggle the right sidebar or manually resize them.`}
+
+ ); + }, +}; + +const serializedGridview: SerializedGridviewComponent = { + grid: { + root: { + type: 'branch', + data: [ + { + type: 'leaf', + data: { + id: 'header-id', + component: 'header', + minimumHeight: 30, + maximumHeight: 30, + }, + }, + { + type: 'branch', + data: [ + { + type: 'leaf', + data: { + id: 'sidebar-id', + component: 'sidebar', + minimumWidth: 30, + maximumWidth: 30, + }, + }, + { + type: 'leaf', + data: { + id: 'left-expander-id', + component: 'left-expander', + minimumWidth: 100, + snap: true, + }, + }, + { + type: 'leaf', + size: 100, + data: { + id: 'main-id', + component: 'main', + minimumWidth: 100, + minimumHeight: 100, + /** + * it's important to give the main content a high layout priority as we want + * the main layout to have priority when allocating new space + */ + priority: LayoutPriority.High, + }, + }, + { + type: 'leaf', + data: { + id: 'right-expander-id', + component: 'right-expander', + snap: true, + minimumWidth: 100, + }, + }, + ], + }, + { + type: 'leaf', + data: { + id: 'footer-id', + component: 'footer', + minimumHeight: 30, + maximumHeight: 30, + }, + }, + ], + }, + width: 1000, + height: 1000, + orientation: Orientation.VERTICAL, + }, +}; + +export const App: React.FC = (props: { theme?: string }) => { + const [api, setApi] = React.useState(); + + const onReady = (event: GridviewReadyEvent) => { + event.api.fromJSON(serializedGridview); + + setApi(event.api); + }; + + const onKeyDown = (event: React.KeyboardEvent) => { + if (!api) { + return; + } + + console.log(event); + + const leftExpander = api.getPanel('left-expander-id'); + const rightExpander = api.getPanel('right-expander-id'); + + if (!leftExpander || !rightExpander) { + return; + } + + switch (event.key) { + case 'b': + if (event.ctrlKey) { + if (event.altKey) { + // toggle right + rightExpander.api.setVisible( + !rightExpander.api.isVisible + ); + if (rightExpander.api.width === 0) { + rightExpander.api.setSize({ width: 150 }); + } + } else { + // toggle left + leftExpander.api.setVisible( + !leftExpander.api.isVisible + ); + if (leftExpander.api.width === 0) { + leftExpander.api.setSize({ width: 150 }); + } + } + } + } + }; + + return ( +
+
+ +
+
+ ); +}; + +export default App; diff --git a/packages/docs/sandboxes/editor-gridview/src/index.tsx b/packages/docs/sandboxes/editor-gridview/src/index.tsx new file mode 100644 index 000000000..2fe1be232 --- /dev/null +++ b/packages/docs/sandboxes/editor-gridview/src/index.tsx @@ -0,0 +1,20 @@ +import { StrictMode } from 'react'; +import * as ReactDOMClient from 'react-dom/client'; +import './styles.css'; +import 'dockview/dist/styles/dockview.css'; + +import App from './app'; + +const rootElement = document.getElementById('root'); + +if (rootElement) { + const root = ReactDOMClient.createRoot(rootElement); + + root.render( + +
+ +
+
+ ); +} diff --git a/packages/docs/sandboxes/editor-gridview/src/styles.css b/packages/docs/sandboxes/editor-gridview/src/styles.css new file mode 100644 index 000000000..92b6a1b36 --- /dev/null +++ b/packages/docs/sandboxes/editor-gridview/src/styles.css @@ -0,0 +1,16 @@ +body { + margin: 0px; + color: white; + font-family: sans-serif; + text-align: center; +} + +#root { + height: 100vh; + width: 100vw; +} + +.app { + height: 100%; + +} diff --git a/packages/docs/sandboxes/editor-gridview/tsconfig.json b/packages/docs/sandboxes/editor-gridview/tsconfig.json new file mode 100644 index 000000000..cdc4fb5f5 --- /dev/null +++ b/packages/docs/sandboxes/editor-gridview/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "outDir": "build/dist", + "module": "esnext", + "target": "es5", + "lib": ["es6", "dom"], + "sourceMap": true, + "allowJs": true, + "jsx": "react-jsx", + "moduleResolution": "node", + "rootDir": "src", + "forceConsistentCasingInFileNames": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": true, + "strictNullChecks": true + } +} diff --git a/packages/docs/sandboxes/simple-gridview/src/app.scss b/packages/docs/sandboxes/simple-gridview/src/app.scss new file mode 100644 index 000000000..a708b2796 --- /dev/null +++ b/packages/docs/sandboxes/simple-gridview/src/app.scss @@ -0,0 +1,3 @@ +.simple-gridview-example { + --dv-active-sash-color: #007acc; +} diff --git a/packages/docs/src/components/ui/codeSandboxButton.tsx b/packages/docs/src/components/ui/codeSandboxButton.tsx index f17a3dec9..7999adb28 100644 --- a/packages/docs/src/components/ui/codeSandboxButton.tsx +++ b/packages/docs/src/components/ui/codeSandboxButton.tsx @@ -32,7 +32,10 @@ const CloseButton = () => path: 'M22.5581 50.9938V30.1717L4.65116 19.869V31.7386L12.8536 36.4939V45.4198L22.5581 50.9938ZM27.2093 51.1162L37.0931 45.4226V36.2851L45.3488 31.501V19.7801L27.2093 30.2529V51.1162ZM42.9633 15.7867L33.4288 10.2615L25.0571 15.1193L16.6219 10.2567L7.00237 15.8557L24.9542 26.1842L42.9633 15.7867ZM0 43.4008V14.5498L24.9974 0L50 14.4887V43.3552L24.9969 57.7584L0 43.4008Z', }); -export const CodeSandboxButton = (props: { id: string }) => { +export const CodeSandboxButton = (props: { + id: string; + hideThemePicker?: boolean; +}) => { const url = React.useMemo(() => { if (!props.id) { return ''; @@ -42,7 +45,7 @@ export const CodeSandboxButton = (props: { id: string }) => { return ( <> - + {!props.hideThemePicker && } { dispose: () => void }; sandboxId: string; height?: number; + hideThemePicker?: boolean; }) => { const ref = React.useRef(null); @@ -266,7 +267,10 @@ export const MultiFrameworkContainer2 = (props: { )} - + ); @@ -277,6 +281,7 @@ export const MultiFrameworkContainer = (props: { typescript?: (parent: HTMLElement) => { dispose: () => void }; sandboxId: string; height?: number; + hideThemePicker?: boolean; }) => { return (