Skip to content

Commit 54eefb3

Browse files
mathuoclaude
andcommitted
docs: improve multi-framework coverage across docs site
- Re-enable Angular in the framework selector UI and add angular-icon.svg - Add Vue, Angular and JavaScript variants to tabs.mdx (custom panel parameters, extend default tab, full-width tab sections) - Add framework-specific theme import snippets to theme.mdx - Add all framework variants to state/load.mdx and state/save.mdx - Add Vue/Angular/JS visibility-gating examples to rendering.mdx - Add Angular and JavaScript DocRef blocks to splitview, gridview and paneview overview pages - Wrap bare React code blocks in controls.mdx and dragAndDrop.mdx and add Vue, Angular and JavaScript equivalents Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent bbec748 commit 54eefb3

File tree

12 files changed

+622
-51
lines changed

12 files changed

+622
-51
lines changed

packages/docs/docs/core/dnd/dragAndDrop.mdx

Lines changed: 80 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,62 @@ The dock makes heavy use of drag and drop functionalities.
2525

2626
You can override the conditions of the far edge overlays through the `dndEdges` prop.
2727

28+
<FrameworkSpecific framework='React'>
2829
```tsx
2930
<DockviewReact
30-
{...props}
31-
dndEdges={{
31+
dndEdges={{
32+
size: { value: 100, type: 'pixels' },
33+
activationSize: { value: 5, type: 'percentage' },
34+
}}
35+
/>
36+
```
37+
</FrameworkSpecific>
38+
39+
<FrameworkSpecific framework='Vue'>
40+
```html
41+
<dockview-vue
42+
:dndEdges="{
43+
size: { value: 100, type: 'pixels' },
44+
activationSize: { value: 5, type: 'percentage' },
45+
}"
46+
/>
47+
```
48+
</FrameworkSpecific>
49+
50+
<FrameworkSpecific framework='Angular'>
51+
```html
52+
<dv-dockview [dndEdges]="dndEdges"></dv-dockview>
53+
```
54+
```ts
55+
dndEdges = {
3256
size: { value: 100, type: 'pixels' },
3357
activationSize: { value: 5, type: 'percentage' },
34-
}}
35-
/>
58+
};
59+
```
60+
</FrameworkSpecific>
61+
62+
<FrameworkSpecific framework='JavaScript'>
63+
```ts
64+
const api = createDockview(parentElement, {
65+
dndEdges: {
66+
size: { value: 100, type: 'pixels' },
67+
activationSize: { value: 5, type: 'percentage' },
68+
},
69+
});
3670
```
71+
</FrameworkSpecific>
3772

3873
## Extended behaviours
3974

4075
For interaction with the Drag events directly the component exposes some method to help determine whether external drag events should be interacted with or not.
4176

42-
```tsx
77+
The `onDidDrop` handler and `onUnhandledDragOverEvent` registration use the same API across all frameworks — only the component wiring differs.
78+
79+
```ts
4380
/**
44-
* called when an ondrop event which does not originate from the dockview libray and
45-
* passes the onUnhandledDragOverEvent condition
46-
**/
81+
* Called when a drop event does not originate from the dockview library
82+
* and passes the onUnhandledDragOverEvent condition.
83+
*/
4784
const onDidDrop = (event: DockviewDropEvent) => {
4885
const { group } = event;
4986

@@ -56,28 +93,52 @@ const onDidDrop = (event: DockviewDropEvent) => {
5693
},
5794
});
5895
};
96+
```
5997

98+
```ts
99+
/**
100+
* Called for drag-over events that do not originate from the dockview library,
101+
* allowing you to decide whether an overlay should be shown.
102+
*/
60103
const onReady = (event: DockviewReadyEvent) => {
104+
event.api.onUnhandledDragOverEvent((e) => {
105+
e.accept();
106+
});
107+
};
108+
```
61109

62-
/**
63-
* called for drag over events which do not originate from the dockview library
64-
* allowing the developer to decide where the overlay should be shown for a
65-
* particular drag event
66-
**/
67-
api.onUnhandledDragOverEvent(event => {
68-
event.accept();
69-
});
70-
}
71-
110+
<FrameworkSpecific framework='React'>
111+
```tsx
72112
return (
73113
<DockviewReact
74114
components={components}
75115
onReady={onReady}
76-
className="dockview-theme-abyss"
77116
onDidDrop={onDidDrop}
78117
/>
79118
);
80119
```
120+
</FrameworkSpecific>
121+
122+
<FrameworkSpecific framework='Vue'>
123+
```html
124+
<dockview-vue @ready="onReady" @didDrop="onDidDrop" />
125+
```
126+
</FrameworkSpecific>
127+
128+
<FrameworkSpecific framework='Angular'>
129+
```html
130+
<dv-dockview (ready)="onReady($event)" (didDrop)="onDidDrop($event)"></dv-dockview>
131+
```
132+
</FrameworkSpecific>
133+
134+
<FrameworkSpecific framework='JavaScript'>
135+
```ts
136+
const api = createDockview(parentElement, { components });
137+
138+
api.onUnhandledDragOverEvent((e) => e.accept());
139+
parentElement.addEventListener('drop', (e) => onDidDrop(e));
140+
```
141+
</FrameworkSpecific>
81142

82143
## Third Party Dnd Libraries
83144

packages/docs/docs/core/groups/controls.mdx

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,94 @@ This section describes how you can customize the header component of each group.
2424
</FrameworkSpecific>
2525

2626

27+
<FrameworkSpecific framework='React'>
2728
```tsx
2829
const LeftComponent = (props: IDockviewHeaderActionsProps) => {
2930
return <div>{/** content */}</div>;
3031
};
3132

3233
const RightComponent = (props: IDockviewHeaderActionsProps) => {
33-
return <div>{/** content */}</div>;
34+
return <div>{/** content */}</div>;
3435
};
3536

3637
const PrefixComponent = (props: IDockviewHeaderActionsProps) => {
3738
return <div>{/** content */}</div>;
3839
};
3940

4041
return <DockviewReact
41-
leftHeaderActionsComponent={LeftComponent}
42-
rightHeaderActionsComponent={RightComponent}
43-
prefixHeaderActionsComponent={PrefixComponent}
42+
leftHeaderActionsComponent={LeftComponent}
43+
rightHeaderActionsComponent={RightComponent}
44+
prefixHeaderActionsComponent={PrefixComponent}
4445
/>;
4546
```
47+
</FrameworkSpecific>
48+
49+
<FrameworkSpecific framework='Vue'>
50+
```vue
51+
<!-- Register components by name, then pass the names to dockview-vue -->
52+
<script setup lang="ts">
53+
import LeftComponent from './LeftComponent.vue';
54+
import RightComponent from './RightComponent.vue';
55+
import PrefixComponent from './PrefixComponent.vue';
56+
</script>
57+
58+
<template>
59+
<dockview-vue
60+
leftHeaderActionsComponent="LeftComponent"
61+
rightHeaderActionsComponent="RightComponent"
62+
prefixHeaderActionsComponent="PrefixComponent"
63+
:components="{ LeftComponent, RightComponent, PrefixComponent }"
64+
/>
65+
</template>
66+
```
67+
</FrameworkSpecific>
68+
69+
<FrameworkSpecific framework='Angular'>
70+
```ts
71+
import { Component } from '@angular/core';
72+
import { LeftComponent } from './left.component';
73+
import { RightComponent } from './right.component';
74+
import { PrefixComponent } from './prefix.component';
75+
76+
@Component({
77+
selector: 'app-root',
78+
template: `
79+
<dv-dockview
80+
[leftHeaderActionsComponent]="leftComponent"
81+
[rightHeaderActionsComponent]="rightComponent"
82+
[prefixHeaderActionsComponent]="prefixComponent"
83+
></dv-dockview>
84+
`,
85+
})
86+
export class AppComponent {
87+
leftComponent = LeftComponent;
88+
rightComponent = RightComponent;
89+
prefixComponent = PrefixComponent;
90+
}
91+
```
92+
</FrameworkSpecific>
93+
94+
<FrameworkSpecific framework='JavaScript'>
95+
```ts
96+
const api = createDockview(parentElement, {
97+
createLeftHeaderActionsElement: (group) => {
98+
const element = document.createElement('div');
99+
// populate element
100+
return { element, dispose: () => {} };
101+
},
102+
createRightHeaderActionsElement: (group) => {
103+
const element = document.createElement('div');
104+
// populate element
105+
return { element, dispose: () => {} };
106+
},
107+
createPrefixHeaderActionsElement: (group) => {
108+
const element = document.createElement('div');
109+
// populate element
110+
return { element, dispose: () => {} };
111+
},
112+
});
113+
```
114+
</FrameworkSpecific>
46115

47116
## Live Example
48117

packages/docs/docs/core/panels/rendering.mdx

Lines changed: 93 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,11 @@ api.addPanel({
7171
<CodeRunner id="dockview/render-mode"/>
7272

7373

74-
By default `DockviewReact` only adds to the DOM those panels that are visible,
75-
if a panel is not the active tab and not shown the contents of the hidden panel will be removed from the DOM.
74+
When a panel uses `always` render mode, the panel component instance is kept alive even when the panel is not visible. This means reactive state, subscriptions, and lifecycle hooks continue to run in the background.
7675

77-
When a panel is in `onlyWhenVisible` render mode this only affects the contents within the DOM. The lifecycle of that panel instance is still maintained.
78-
The React Components associated with each panel are only created once and will always exist for as long as the panel exists, hidden or not.
79-
80-
> e.g. This means that any hooks in those components will run whether the panel is visible or not which may lead to excessive background work depending
81-
> on the panels implementation.
82-
83-
You can listen to the visiblity state of the panel and write additional logic to optimize your application if required, although this is an advanced case.
84-
85-
If you wanted to unmount the React Components when the panel is not visible you could create a Higher-Order-Component that listens to the panels
86-
visiblity state and only renders the panel when visible.
76+
You can listen to `onDidVisibilityChange` to gate expensive work, or conditionally render inner content only when the panel is visible.
8777

78+
<FrameworkSpecific framework='React'>
8879
```tsx title="Only rendering the React Component when the panel is visible, otherwise rendering a null React Component"
8980
import { IDockviewPanelProps } from 'dockview';
9081
import * as React from 'react';
@@ -120,8 +111,97 @@ function RenderWhenVisible(
120111
```tsx
121112
const components = { default: RenderWhenVisible(MyComponent) };
122113
```
114+
</FrameworkSpecific>
115+
116+
<FrameworkSpecific framework='Vue'>
117+
```vue title="Conditionally rendering content based on panel visibility"
118+
<script setup lang="ts">
119+
import { ref, onMounted, onUnmounted } from 'vue';
120+
import type { IDockviewPanelProps } from 'dockview-vue';
121+
122+
const props = defineProps<IDockviewPanelProps>();
123+
124+
const visible = ref(props.api.isVisible);
125+
126+
const disposable = props.api.onDidVisibilityChange((event) => {
127+
visible.value = event.isVisible;
128+
});
129+
130+
onUnmounted(() => {
131+
disposable.dispose();
132+
});
133+
</script>
134+
135+
<template>
136+
<template v-if="visible">
137+
<!-- expensive panel content — only mounted when panel is visible -->
138+
</template>
139+
</template>
140+
```
141+
</FrameworkSpecific>
142+
143+
<FrameworkSpecific framework='Angular'>
144+
```ts title="Conditionally rendering content based on panel visibility"
145+
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
146+
import type { DockviewPanelApi } from 'dockview-angular';
147+
148+
@Component({
149+
selector: 'my-panel',
150+
template: `
151+
<ng-container *ngIf="visible">
152+
<!-- expensive panel content — only rendered when panel is visible -->
153+
</ng-container>
154+
`,
155+
})
156+
export class MyPanel implements OnInit, OnDestroy {
157+
@Input() api: DockviewPanelApi;
158+
159+
visible = false;
160+
private disposable: { dispose(): void };
161+
162+
ngOnInit() {
163+
this.visible = this.api.isVisible;
164+
this.disposable = this.api.onDidVisibilityChange((event) => {
165+
this.visible = event.isVisible;
166+
});
167+
}
168+
169+
ngOnDestroy() {
170+
this.disposable?.dispose();
171+
}
172+
}
173+
```
174+
</FrameworkSpecific>
175+
176+
<FrameworkSpecific framework='JavaScript'>
177+
```ts title="Gating work based on panel visibility"
178+
class MyPanel implements IContentRenderer {
179+
private readonly _element: HTMLElement;
180+
181+
get element() {
182+
return this._element;
183+
}
184+
185+
constructor() {
186+
this._element = document.createElement('div');
187+
}
188+
189+
init(parameters: GroupviewPanelState): void {
190+
parameters.api.onDidVisibilityChange((event) => {
191+
if (event.isVisible) {
192+
// panel is now visible — start expensive work
193+
} else {
194+
// panel is hidden — pause expensive work
195+
}
196+
});
197+
}
198+
199+
dispose(): void {}
200+
}
201+
```
202+
</FrameworkSpecific>
123203

124-
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.
204+
Toggling the checkbox in the live example shows the panel component being destroyed when hidden and re-created when it becomes visible again.
125205

126206

127207
<MultiFrameworkContainer

0 commit comments

Comments
 (0)