Dock manager
@xui/dock-managerAn IDE-style docking layout driven by one serialisable tree: resizable split panes, tab groups, a document host for editor tabs, panes that collapse to the edges, and floating windows. Drag a pane header or tab and Visual Studio's docking targets appear: a five-way joystick over the pane under the pointer — arms to split it, centre to tab with it — plus an outer ring at the edges for docking against the whole layout. The target that would be used lights up and an outline previews the space it would take. Drop outside the layout to float the pane. Every action is also on the header: pin, float, maximize, close. Splitter gutters take arrow keys, and tab strips take arrow/Home/End. A pane's body is declared once as <ng-template xuiDockContent="id"> and then *moved* rather than rebuilt, so scroll position and half-typed input survive a drag.
Install
pnpm add @xui/dock-manager Add the barrel to a standalone component's imports:
import { XuiDockManagerImports } from '@xui/dock-manager';
@Component({
imports: [XuiDockManagerImports],
// …
})Examples
Default
<xui-dock-manager [(layout)]="layout" class="border-border h-[26rem] w-[52rem] rounded-lg border">
<ng-template xuiDockContent="explorer"></ng-template>
<ng-template xuiDockContent="details"></ng-template>
</xui-dock-manager>Ide
<xui-dock-manager [(layout)]="layout" class="border-border h-[34rem] w-[60rem] rounded-lg border">
<ng-template xuiDockContent="explorer"></ng-template>
<!-- A bare "{" would start an ICU expression in an Angular template. -->
<ng-template xuiDockContent="doc1"></ng-template>
<ng-template xuiDockContent="doc2"></ng-template>
<ng-template xuiDockContent="terminal">
<pre class="text-foreground-muted m-0 p-3 text-xs">$ nx build dock-manager
Built @xui/dock-manager</pre>
</ng-template>
<ng-template xuiDockContent="problems"></ng-template>
<ng-template xuiDockContent="outline"></ng-template>
<ng-template xuiDockContent="search">
<div class="p-2">
<input xuiInput size="sm" class="w-full" type="search" placeholder="Search…" />
</div>
</ng-template>
</xui-dock-manager>Preserves content
<xui-dock-manager [(layout)]="layout" class="border-border h-[22rem] w-[46rem] rounded-lg border">
<ng-template xuiDockContent="form">
<div class="flex flex-col gap-2 p-3">
<input xuiInput size="sm" placeholder="Type something, then drag this pane" />
<textarea xuiTextarea size="sm" class="h-24" aria-label="Notes"></textarea>
</div>
</ng-template>
<ng-template xuiDockContent="notes"></ng-template>
</xui-dock-manager>Restricted panes
<xui-dock-manager [(layout)]="layout" class="border-border h-[20rem] w-[52rem] rounded-lg border">
<ng-template xuiDockContent="fixed"></ng-template>
<ng-template xuiDockContent="anchored"></ng-template>
<ng-template xuiDockContent="free"></ng-template>
</xui-dock-manager>Right to left
<div dir="rtl">
<xui-dock-manager [(layout)]="layout" class="border-border h-[20rem] w-[46rem] rounded-lg border">
<ng-template xuiDockContent="explorer"></ng-template>
<ng-template xuiDockContent="details"></ng-template>
</xui-dock-manager>
</div>API
Declares the body of one content pane.
Inputs
contentIdstringMatches the contentId of a content pane in the layout.Fills its host element with the content view for a contentId.
Inputs
contentIdstringWhich pane's content view to mount here — the contentId of the matching xuiDockContent.An IDE-style docking layout: resizable split panes, tab groups, a document host, collapsible edge panels and floating windows, all driven by one serialisable {@link XuiDockManagerLayout} tree.
Inputs
classClassValueExtra classes, merged into the component's own rather than replacing them.''layoutXuiDockManagerLayoutThe layout tree. Two-way bindable, and edited **in place** — see the class docs for why, and use cloneDockLayout() for snapshots.Outputs
paneCloseXuiDockContentPaneA pane was closed and removed from the layout.activePaneChangeXuiDockContentPane | nullThe pane the user last interacted with, or null once it is gone.panePinnedChangeXuiDockPaneStateEventEmits the pane and its new pinned state whenever a pane is pinned or unpinned.paneMaximizedChangeXuiDockPaneStateEventEmits the pane and its new maximized state whenever a pane is maximized or restored.paneFloatingChangeXuiDockPaneStateEventEmits the pane and its new floating state whenever a pane is torn out of the layout or docked back into it.paneDragStartXuiDockPaneA pointer drag on a pane header or tab began.paneDragEndXuiDockPaneA pointer drag ended, whether or not it changed the layout.Methods
mountContent(contentId: string, host: HTMLElement): voidreleaseContent(contentId: string, host: HTMLElement): voidclosePane(pane: XuiDockContentPane): voidRemove pane from the layout. Respects allowClose.closeWindow(window: XuiDockSplitPane): voidClose every pane in a floating window.unpinPane(pane: XuiDockContentPane): voidCollapse pane to a tab on the nearest edge, keeping its place in the tree.pinPane(pane: XuiDockContentPane): voidRestore pane to the position it was collapsed from.togglePinned(pane: XuiDockContentPane): voidmaximizePane(pane: XuiDockContentPane): voidBlow pane up to fill the whole dock manager, hiding everything else.restorePane(pane: XuiDockContentPane): voidtoggleMaximized(pane: XuiDockContentPane): voidfloatPane(pane: XuiDockPane, location?: XuiDockPoint, size?: { width: number; height: number }): voidMove pane into a floating window of its own.dockPane(pane: XuiDockPane, target: XuiDockPane, position: XuiDockPosition): booleanDock pane at position relative to target.selectPane(pane: XuiDockContentPane): voidMake pane the active one, selecting its tab and opening its fly-out.