Tabs
This is a guide, not the contract. What the platform guarantees is specified under
openspec/specs/. For this page:content-tabs·host-services. Where this page and a specification disagree, the specification is right, and that is a defect in this page: change the behaviour there, then explain it here.
The content area is router-addressed, so most navigation is just routing. This service is for the things routing alone cannot express: the tab strip’s own state.
Do it
const tabs = inject(ContentTabsService);
tabs.navigateTo('doc/readme'); // navigate, fire-and-forgettabs.open({ path: 'doc/readme', title: 'README.md', titleIsLiteral: true }); // a titled dynamic tabtabs.open({ path: 'doc/readme', badge: { text: 'Draft', textIsLiteral: true } }); // refine it with a badge; null removes ittabs.keep('doc/readme'); // promote a preview tabtabs.pin('doc/readme'); tabs.unpin('doc/readme');tabs.close('doc/readme'); tabs.closeOthers('doc/readme');tabs.closeToRight('doc/readme'); tabs.closeAll();tabs.revealContentTab('doc/readme'); // focus the tab where it already livestabs.update('doc/readme', { badge: null }); // change an open tab's label in place, never bringing it forwardUse navigateTo when the address alone says what to show; use open when the tab needs a title the address does not carry, or should open as a preview.
Read it
tabs.activeContent(); // { surfaceId, path, params } | nulltabs.tabs(); // the visible striptabs.quickOpenTargets(); // everything `mod+p` can reachtabs.hasUnsavedWork('doc/42'); // boolean, read reactivelyWhat is active is activeContent(): the surface, its path and its parameters, or null, as a plugin reads it through ctx.activeContent. The strip is tabs(), in strip order. What quick-open can reach is quickOpenTargets(): the open tabs, and the unopened routes the session may open.
Whether an address holds unsaved work is hasUnsavedWork(path): the fact behind the mark the
workbench draws on the tab. Draw your own with it where the workbench does not reach, a badge in your
status bar or a count beside a module. Read it in a computed or a template and it follows the work
being saved. An arrangement answers for what is inside it, and the answer covers every pane the
address is open in.
What asks about unsaved work
close, closeOthers, closeToRight and closeAll ask about unsaved work exactly as the × and the tab menu do, through the same guard. They close only what the answer allows.
Switched off
content.close, content.pin, content.preview and content.escalate take the user’s controls away; every method here keeps working for you.
In depth
Reveal, do not duplicate. revealContentTab is the one to reach for when a tab may live in a
split pane. It activates the tab in place and that pane takes the address, instead of opening a
second copy in the address pane.
Scope. This page is about what the panes hold. The content area’s arrangement, splits and panes, is Panes.
Where the story is told
- Content area: routes and tabs: how a surface becomes a tab.
- Following tabs: tabs whose address is computed.
- Routing: what carries over from the Angular router unchanged.