Skip to main content

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:

IdCSS 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:

ValueBehaviour
'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:

PropertyDefaultDescription
--dv-tab-group-color-grey#5f6368Colour for grey chips
--dv-tab-group-color-blue#1a73e8Colour for blue chips
--dv-tab-group-color-red#d93025Colour for red chips
--dv-tab-group-color-yellow#f9ab00Colour for yellow chips
--dv-tab-group-color-green#188038Colour for green chips
--dv-tab-group-color-pink#d01884Colour for pink chips
--dv-tab-group-color-purple#a142f4Colour for purple chips
--dv-tab-group-color-cyan#007b83Colour for cyan chips
--dv-tab-group-color-orange#e8710aColour for orange chips
--dv-tab-group-chip-padding4px 8pxChip padding
--dv-tab-group-chip-border-radius6pxChip border radius
--dv-tab-group-chip-font-size11pxChip font size
--dv-tab-group-line-height2pxHeight of the colored underline beneath grouped tabs
--dv-tab-group-line-opacity0.6Opacity 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>;
}