Skip to content

Commit 564a724

Browse files
authored
Merge pull request #1171 from mathuo/docs/tab-groups-and-edge-groups-documentation
docs: complete tab groups and edge groups documentation
2 parents 9c2b2a3 + d9fbb79 commit 564a724

10 files changed

Lines changed: 801 additions & 6 deletions

File tree

packages/dockview-core/src/dockview/options.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,10 @@ export interface DockviewOptions {
159159
/**
160160
* Return the items to display in the tab group chip context menu on right-click.
161161
*
162-
* Use built-in string shortcuts (`'separator'`, `'colorPicker'`) or provide a
162+
* Use built-in string shortcuts (`'separator'`, `'colorPicker'`, `'rename'`) or provide a
163163
* `ContextMenuItemConfig` object for custom items.
164164
* `'colorPicker'` renders a native grid of color swatches for the tab group.
165+
* `'rename'` renders an inline text input to rename the tab group.
165166
*
166167
* If omitted, no context menu is shown on chip right-click.
167168
* Return an empty array to suppress the menu for specific cases.

packages/docs/docs/core/groups/edgeGroups.mdx

Lines changed: 94 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,20 @@ description: How to create and manage edge groups in Dockview — groups that ar
55

66
import { DocRef } from '@site/src/components/ui/reference/docRef';
77

8+
import { CodeRunner } from '@site/src/components/ui/codeRunner';
9+
810
Edge groups are `DockviewGroupPanel` instances pinned to one of the four edges of the layout (`'left'`, `'right'`, `'top'`, `'bottom'`). They support tabs, drag-and-drop, overflow, and the full group panel API — and their state is included in `toJSON` / `fromJSON`.
911

12+
<CodeRunner id="dockview/edge-groups" height={500}/>
13+
1014
:::info
1115
Edge groups **cannot** be maximized or converted into floating/popout windows. They are structural elements of the layout.
1216
:::
1317

18+
:::tip
19+
The `dndEdges` prop controls the drag-and-drop overlay that appears when dragging panels to the far edges of the layout. See [Drag and Drop](/docs/core/dnd/dragAndDrop#drag-and-drop) for configuration details.
20+
:::
21+
1422
## Adding Edge Groups
1523

1624
Call `addEdgeGroup` in your `onReady` handler (or any time after initialization):
@@ -113,20 +121,101 @@ const isCollapsed = groupApi?.isCollapsed(); // boolean
113121

114122
The `collapsedSize` (the pixel height/width of the header when collapsed) defaults to 35px and can be configured per-group via `EdgeGroupOptions.collapsedSize`, or per-theme via `DockviewTheme.edgeGroupCollapsedSize`.
115123

124+
Themes that set a custom `edgeGroupCollapsedSize`:
125+
126+
| Theme | `edgeGroupCollapsedSize` |
127+
| --- | --- |
128+
| `themeVisualStudio` | `22` |
129+
| `themeAbyssSpaced` | `44` |
130+
| `themeGithubLightSpaced` | `44` |
131+
| All other themes | `35` (default) |
132+
133+
:::tip
134+
When an edge group loses all of its panels it is automatically collapsed. Adding a new panel to it will expand it again.
135+
:::
136+
116137
## Custom Header Actions
117138

118-
The `location` prop in `rightHeaderActionsComponent`, `leftHeaderActionsComponent`, and `prefixHeaderActionsComponent` updates reactively when a group moves. Use it to show controls specific to edge groups:
139+
The `location` prop in `rightHeaderActionsComponent`, `leftHeaderActionsComponent`, and `prefixHeaderActionsComponent` updates reactively when a group moves. Use it to show controls specific to edge groups.
140+
141+
The `DockviewGroupLocation` type is a discriminated union:
142+
143+
```ts
144+
type DockviewGroupLocation =
145+
| { type: 'grid' }
146+
| { type: 'floating' }
147+
| { type: 'popout'; getWindow: () => Window }
148+
| { type: 'edge'; position: EdgeGroupPosition }; // 'top' | 'bottom' | 'left' | 'right'
149+
```
150+
151+
Check `location.type` to distinguish edge groups, and `location.position` to know which edge:
119152

153+
<FrameworkSpecific framework="React">
120154
```tsx
121-
// React: show a collapse button only in edge groups
122-
const MyRightActions = (props: IDockviewGroupHeaderActionsProps) => {
123-
if (props.location.type !== 'fixed') return null;
124-
return <button onClick={() => props.api.collapse()}>Collapse</button>;
155+
const MyRightActions = (props: IDockviewHeaderActionsProps) => {
156+
if (props.location?.type !== 'edge') return null;
157+
158+
const position = props.location.position; // 'left' | 'right' | 'top' | 'bottom'
159+
return <button onClick={() => props.api.collapse()}>Collapse {position}</button>;
125160
};
161+
162+
<DockviewReact rightHeaderActionsComponent={MyRightActions} />
163+
```
164+
</FrameworkSpecific>
165+
166+
<FrameworkSpecific framework="Vue">
167+
```vue
168+
<template>
169+
<button v-if="params?.location?.type === 'edge'" @click="params.api.collapse()">
170+
Collapse {{ params.location.position }}
171+
</button>
172+
</template>
173+
```
174+
</FrameworkSpecific>
175+
176+
<FrameworkSpecific framework="Angular">
177+
```ts
178+
@Component({
179+
selector: 'my-right-actions',
180+
template: `
181+
<button *ngIf="location?.type === 'edge'" (click)="api.collapse()">
182+
Collapse {{ location.position }}
183+
</button>
184+
`,
185+
})
186+
export class MyRightActionsComponent {
187+
@Input() api: DockviewGroupPanelApi;
188+
@Input() location: DockviewGroupLocation;
189+
}
190+
```
191+
</FrameworkSpecific>
192+
193+
<FrameworkSpecific framework="JavaScript">
194+
```ts
195+
const api = createDockview(parentElement, {
196+
createRightHeaderActionsElement: (group) => {
197+
const element = document.createElement('div');
198+
return {
199+
element,
200+
init(params) {
201+
if (params.location?.type === 'edge') {
202+
const btn = document.createElement('button');
203+
btn.textContent = `Collapse ${params.location.position}`;
204+
btn.addEventListener('click', () => params.api.collapse());
205+
element.appendChild(btn);
206+
}
207+
},
208+
dispose() {},
209+
};
210+
},
211+
});
126212
```
213+
</FrameworkSpecific>
127214

128215
`DockviewGroupLocation` is exported from all framework packages.
129216

217+
> See [Group Controls](/docs/core/groups/controls) for the full header actions reference.
218+
130219
## Serialization
131220

132221
Edge group state (size, visibility, collapsed state, and panel contents) is included in `toJSON` / `fromJSON` automatically.

packages/docs/docs/core/panels/tabs.mdx

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,13 @@ api.dissolveTabGroup({
675675
groupId: 'group-1',
676676
tabGroupId: tabGroup.id,
677677
});
678+
679+
// Move a tab group to a new position in the tab bar
680+
api.moveTabGroup({
681+
groupId: 'group-1',
682+
tabGroupId: tabGroup.id,
683+
index: 0, // move to the beginning
684+
});
678685
```
679686

680687
### Querying Tab Groups
@@ -743,6 +750,150 @@ tabGroup.onDidDestroy(() => { });
743750

744751
> See [Events](/docs/core/events#tab-groups) for the full event reference.
745752

753+
### Chip Context Menu
754+
755+
Right-clicking a tab group chip can show a context menu. This is opt-in — no menu is shown unless
756+
`getTabGroupChipContextMenuItems` is provided. Return an empty array to suppress the menu for specific chips.
757+
758+
<FrameworkSpecific framework="React">
759+
<DocRef declaration="IDockviewReactProps" methods={['getTabGroupChipContextMenuItems']} />
760+
</FrameworkSpecific>
761+
762+
<FrameworkSpecific framework="Vue">
763+
<DocRef declaration="IDockviewVueProps" methods={['getTabGroupChipContextMenuItems']} />
764+
</FrameworkSpecific>
765+
766+
<FrameworkSpecific framework="Angular">
767+
<DocRef declaration="IDockviewAngularProps" methods={['getTabGroupChipContextMenuItems']} />
768+
</FrameworkSpecific>
769+
770+
<FrameworkSpecific framework="JavaScript">
771+
<DocRef declaration="DockviewComponentOptions" methods={['getTabGroupChipContextMenuItems']} />
772+
</FrameworkSpecific>
773+
774+
#### Built-in items
775+
776+
Pass string shortcuts to render standard menu entries without any extra code:
777+
778+
| Value | Behaviour |
779+
| --- | --- |
780+
| `'rename'` | An inline text input to rename the tab group |
781+
| `'colorPicker'` | A grid of color swatches to change the tab group color |
782+
| `'separator'` | Render a visual divider |
783+
784+
#### Custom label items
785+
786+
Provide an object with a `label` and `action` to add a simple clickable entry:
787+
788+
```ts
789+
getTabGroupChipContextMenuItems: (params) => [
790+
'rename',
791+
'colorPicker',
792+
'separator',
793+
{ label: 'Dissolve group', action: () => params.api.dissolveTabGroup({ groupId: params.group.id, tabGroupId: params.tabGroup.id }) },
794+
]
795+
```
796+
797+
### Custom Chip Renderer
798+
799+
To fully customize how tab group chips look, provide a `createTabGroupChipComponent` factory. It receives the `ITabGroup` and must return an `ITabGroupChipRenderer`.
800+
801+
<FrameworkSpecific framework="React">
802+
<DocRef declaration="IDockviewReactProps" methods={['createTabGroupChipComponent']} />
803+
</FrameworkSpecific>
804+
805+
<FrameworkSpecific framework="Vue">
806+
<DocRef declaration="IDockviewVueProps" methods={['createTabGroupChipComponent']} />
807+
</FrameworkSpecific>
808+
809+
<FrameworkSpecific framework="Angular">
810+
<DocRef declaration="IDockviewAngularProps" methods={['createTabGroupChipComponent']} />
811+
</FrameworkSpecific>
812+
813+
<FrameworkSpecific framework="JavaScript">
814+
<DocRef declaration="DockviewComponentOptions" methods={['createTabGroupChipComponent']} />
815+
</FrameworkSpecific>
816+
817+
The renderer must implement:
818+
819+
```ts
820+
interface ITabGroupChipRenderer {
821+
readonly element: HTMLElement; // the chip DOM element
822+
init(params: { tabGroup: ITabGroup; api: DockviewApi }): void;
823+
update?(params: { tabGroup: ITabGroup }): void; // called when label or color changes
824+
dispose(): void;
825+
}
826+
```
827+
828+
<FrameworkSpecific framework="JavaScript">
829+
```ts
830+
class MyChipRenderer {
831+
readonly element = document.createElement('div');
832+
833+
init({ tabGroup, api }) {
834+
this.element.className = 'my-chip';
835+
this.element.textContent = tabGroup.label;
836+
}
837+
838+
update({ tabGroup }) {
839+
this.element.textContent = tabGroup.label;
840+
}
841+
842+
dispose() {}
843+
}
844+
845+
const api = createDockview(parentElement, {
846+
createTabGroupChipComponent: (tabGroup) => new MyChipRenderer(),
847+
});
848+
```
849+
</FrameworkSpecific>
850+
851+
### Styling
852+
853+
Tab group appearance can be customized through CSS custom properties:
854+
855+
| Property | Default | Description |
856+
| --- | --- | --- |
857+
| `--dv-tab-group-color-grey` | `#5f6368` | Color for grey chips |
858+
| `--dv-tab-group-color-blue` | `#1a73e8` | Color for blue chips |
859+
| `--dv-tab-group-color-red` | `#d93025` | Color for red chips |
860+
| `--dv-tab-group-color-yellow` | `#f9ab00` | Color for yellow chips |
861+
| `--dv-tab-group-color-green` | `#188038` | Color for green chips |
862+
| `--dv-tab-group-color-pink` | `#d01884` | Color for pink chips |
863+
| `--dv-tab-group-color-purple` | `#a142f4` | Color for purple chips |
864+
| `--dv-tab-group-color-cyan` | `#007b83` | Color for cyan chips |
865+
| `--dv-tab-group-color-orange` | `#e8710a` | Color for orange chips |
866+
| `--dv-tab-group-chip-padding` | `4px 8px` | Chip padding |
867+
| `--dv-tab-group-chip-border-radius` | `6px` | Chip border radius |
868+
| `--dv-tab-group-chip-font-size` | `11px` | Chip font size |
869+
| `--dv-tab-group-line-height` | `2px` | Height of the colored underline beneath grouped tabs |
870+
| `--dv-tab-group-line-opacity` | `0.6` | Opacity of the colored underline |
871+
872+
### Serialization
873+
874+
Tab groups are included in `toJSON` / `fromJSON` automatically. Each tab group is serialized as:
875+
876+
```ts
877+
interface SerializedTabGroup {
878+
id: string;
879+
label?: string;
880+
color: DockviewTabGroupColor;
881+
collapsed: boolean;
882+
panelIds: string[];
883+
}
884+
```
885+
886+
### Utilities
887+
888+
Use `isValidTabGroupColor` to validate a string as a tab group color at runtime:
889+
890+
```ts
891+
import { isValidTabGroupColor } from 'dockview';
892+
893+
isValidTabGroupColor('blue'); // true
894+
isValidTabGroupColor('foo'); // false — type narrows to never
895+
```
896+
746897
## Tab Height
747898
748899
Tab height can be controlled through CSS.

0 commit comments

Comments
 (0)