Tab groups
Tab groups let you visually organise tabs within a panel using coloured chips. Tabs can be grouped, collapsed, expanded, recoloured, and reordered via drag and drop. Right-click a chip or tab to see available actions.
Creating and managing tab groups
Use DockviewApi to create tab groups and assign panels to them:
// Create a tab group in a specific group panel
const tabGroup = api.createTabGroup({
groupId: 'group-1',
label: 'My Group',
color: 'blue',
});
// Add panels to the tab group
api.addPanelToTabGroup({
groupId: 'group-1',
tabGroupId: tabGroup.id,
panelId: 'panel-1',
});
// Remove a panel from its tab group
api.removePanelFromTabGroup({
groupId: 'group-1',
panelId: 'panel-1',
});
// Dissolve a tab group (removes all panels from it and destroys it)
api.dissolveTabGroup({
groupId: 'group-1',
tabGroupId: tabGroup.id,
});
// Move a tab group to a new position in the tab bar
api.moveTabGroup({
groupId: 'group-1',
tabGroupId: tabGroup.id,
index: 0, // move to the beginning
});
Querying tab groups
// Get all tab groups in a group panel
const tabGroups = api.getTabGroups({ groupId: 'group-1' });
// Find which tab group a panel belongs to
const tabGroup = api.getTabGroupForPanel({
groupId: 'group-1',
panelId: 'panel-1',
});
ITabGroup
The ITabGroup interface provides methods to read and modify a tab group:
tabGroup.id; // readonly string
tabGroup.label; // readonly string
tabGroup.color; // readonly string | undefined
tabGroup.collapsed; // readonly boolean
tabGroup.panelIds; // readonly string[]
tabGroup.size; // readonly number (panel count)
tabGroup.isEmpty; // readonly boolean
tabGroup.componentParams; // readonly Record<string, unknown> | undefined
// Modify properties
tabGroup.setLabel('New Label');
tabGroup.setColor('red'); // palette id
tabGroup.setColor('#abc123'); // raw CSS literal
tabGroup.setColor(undefined); // clear
tabGroup.setComponentParams({ icon: 'star' });
// Collapse and expand
tabGroup.collapse();
tabGroup.expand();
tabGroup.toggle();
// Panel membership
tabGroup.containsPanel('panel-1');
tabGroup.indexOfPanel('panel-1');
Colour palette
tabGroup.color is any CSS colour string: either an id from the active palette
or a raw CSS literal ('#abc123', 'rgb(...)'). Resolution to a concrete value
is handled by Dockview's colour palette.
The default palette ships with 9 named entries:
| Id | CSS variable |
|---|---|
grey | --dv-tab-group-color-grey |
blue | --dv-tab-group-color-blue |
red | --dv-tab-group-color-red |
yellow | --dv-tab-group-color-yellow |
green | --dv-tab-group-color-green |
pink | --dv-tab-group-color-pink |
purple | --dv-tab-group-color-purple |
cyan | --dv-tab-group-color-cyan |
orange | --dv-tab-group-color-orange |
The default palette references these CSS vars, so you can re-skin the defaults
purely via CSS overrides. The full set is exported as DEFAULT_TAB_GROUP_COLORS.
Custom palette
Replace the default palette with tabGroupColors. The list fully replaces the
defaults; there is no merge. Each entry needs an id (stored on tabGroup.color
and serialized) and a value (any CSS colour expression). An optional label
appears as a tooltip in the context-menu picker.
const tabGroupColors = [
{ id: 'sunset', value: '#ff6b35', label: 'Sunset' },
{ id: 'ocean', value: '#118ab2', label: 'Ocean' },
{ id: 'forest', value: '#06d6a0', label: 'Forest' },
];
The active palette is exposed on the api as api.tabGroupColors for custom
chip renderers that want to read from it (e.g. to render their own picker).
Disabling colour
Set tabGroupAccent: 'off' to opt out of the built-in colour concept entirely.
Dockview stops writing the --dv-tab-group-color custom property, hides
the colour picker, and applies dv-tab-group-chip--accent-off to chips. The
tabGroup.color field is still preserved as data, so pair this with a
createTabGroupChipComponent to own the chip visual end-to-end.
Component params
Use componentParams to attach free-form data to a tab group, typically
consumed by a custom chip renderer. The value is a Record<string, unknown>
that round-trips through toJSON / fromJSON, so it must be JSON-serializable.
const tabGroup = api.createTabGroup({
groupId: 'group-1',
label: 'Trading',
componentParams: { icon: '📊', priority: 1 },
});
// Update at runtime, fires onDidChange so a custom chip can re-render
tabGroup.setComponentParams({ icon: '⭐️', priority: 1 });
Events
Tab group lifecycle events are available on DockviewApi:
api.onDidCreateTabGroup((event) => {});
api.onDidDestroyTabGroup((event) => {});
api.onDidAddPanelToTabGroup((event) => {});
api.onDidRemovePanelFromTabGroup((event) => {});
api.onDidTabGroupChange((event) => {});
api.onDidTabGroupCollapsedChange((event) => {});
Individual tab groups also expose events:
tabGroup.onDidChange(() => {}); // label or color changed
tabGroup.onDidCollapseChange((collapsed) => {});
tabGroup.onDidPanelChange(({ panelId, type }) => {}); // 'add' | 'remove'
tabGroup.onDidDestroy(() => {});
See Events for the full event reference.
Chip context menu
Right-clicking a tab group chip can show a context menu. This is opt-in; no menu is shown unless
getTabGroupChipContextMenuItems is provided. Return an empty array to suppress the menu for specific chips.
The chip context menu is an enterprise context menu feature. Everything else on this page (chips, colours, custom chip renderers, events, and serialization) is part of the free core; only this menu needs the enterprise package.
Built-in items
Pass string shortcuts to render standard menu entries without any extra code:
| Value | Behaviour |
|---|---|
'rename' | An inline text input to rename the tab group |
'colorPicker' | A grid of colour swatches to change the tab group colour |
'collapse' | Collapse the tab group. Renders as Expand when already collapsed |
'close' | Close every panel belonging to the tab group |
'separator' | Render a visual divider |
Custom label items
Provide an object with a label and action to add a simple clickable entry:
getTabGroupChipContextMenuItems: (params) => [
'rename',
'colorPicker',
'separator',
{
label: 'Dissolve group',
action: () =>
params.api.dissolveTabGroup({
groupId: params.group.id,
tabGroupId: params.tabGroup.id,
}),
},
];
Custom chip renderer
To fully customise how tab group chips look, provide a createTabGroupChipComponent factory. It receives the ITabGroup and must return an ITabGroupChipRenderer.
The renderer must implement:
interface ITabGroupChipRenderer {
readonly element: HTMLElement; // the chip DOM element
init(params: { tabGroup: ITabGroup; api: DockviewApi }): void;
update?(params: { tabGroup: ITabGroup }): void; // called when label, color or componentParams change
dispose(): void;
}
Read tabGroup.componentParams inside init / update to access free-form
data attached to the group, and listen on tabGroup.onDidChange to re-render
when the value mutates.
Styling
Tab group appearance can be customised through CSS custom properties:
| Property | Default | Description |
|---|---|---|
--dv-tab-group-color-grey | #5f6368 | Colour for grey chips |
--dv-tab-group-color-blue | #1a73e8 | Colour for blue chips |
--dv-tab-group-color-red | #d93025 | Colour for red chips |
--dv-tab-group-color-yellow | #f9ab00 | Colour for yellow chips |
--dv-tab-group-color-green | #188038 | Colour for green chips |
--dv-tab-group-color-pink | #d01884 | Colour for pink chips |
--dv-tab-group-color-purple | #a142f4 | Colour for purple chips |
--dv-tab-group-color-cyan | #007b83 | Colour for cyan chips |
--dv-tab-group-color-orange | #e8710a | Colour for orange chips |
--dv-tab-group-chip-padding | 4px 8px | Chip padding |
--dv-tab-group-chip-border-radius | 6px | Chip border radius |
--dv-tab-group-chip-font-size | 11px | Chip font size |
--dv-tab-group-line-height | 2px | Height of the colored underline beneath grouped tabs |
--dv-tab-group-line-opacity | 0.6 | Opacity of the colored underline |
Serialization
Tab groups are included in toJSON / fromJSON automatically. Each tab group is serialized as:
interface SerializedTabGroup {
id: string;
label?: string;
color?: string;
collapsed: boolean;
panelIds: string[];
componentParams?: Record<string, unknown>;
}