Blazorise DockLayout component

Build IDE-like workspaces with docked panes, document areas, tab groups, splitters, auto-hide panes, and restorable layout state.

The <DockLayout> component owns the docking tree and state for a workspace. Use <DockPane> for tool and document panes, and give each pane a stable Name so state can be saved and restored later.

A pane can start on the left, right, top, bottom, or center document area. Users can move panes by dragging their headers, resize panes with splitters, group panes as tabs, auto-hide side panes, and close panes when enabled.

For simple layouts, place panes directly inside DockLayout. For advanced starting layouts, combine DockSplit and DockTabs to predefine the initial split and tab structure.

Examples

Basic workspace

A typical workspace uses a top toolbar, left explorer, center document pane, right properties pane, and bottom output pane.
<DockLayout Style="height: 28rem;" PaneBordered>
    <DockPane Name="toolbar" Caption="Toolbar" PanePosition="DockPanePosition.Top" Role="DockPaneRole.Tool" Resizable="false" ShowTab="false" AutoHideable="false" Closable="false">
        <DockPaneBody>
            Toolbar
        </DockPaneBody>
    </DockPane>

    <DockPane Name="explorer" Caption="Explorer" PanePosition="DockPanePosition.Left" Size="16rem" MinSize="10rem" Resizable>
        <DockPaneHeader>
            <Strong>Explorer</Strong>
        </DockPaneHeader>
        <DockPaneBody>
            Content 1
        </DockPaneBody>
    </DockPane>

    <DockPane Name="designer" Caption="Designer" PanePosition="DockPanePosition.Center" Role="DockPaneRole.Document" ShowTab="false" Closable="false">
        <DockPaneHeader>
            <Strong>Designer</Strong>
        </DockPaneHeader>
        <DockPaneBody>
            Content 2
        </DockPaneBody>
    </DockPane>

    <DockPane Name="properties" Caption="Properties" PanePosition="DockPanePosition.Right" Size="18rem" MinSize="12rem" Resizable>
        <DockPaneHeader>
            <Strong>Properties</Strong>
        </DockPaneHeader>
        <DockPaneBody>
            Content 3
        </DockPaneBody>
    </DockPane>

    <DockPane Name="output" Caption="Output" PanePosition="DockPanePosition.Bottom" Size="6rem" MinSize="4rem" Resizable>
        <DockPaneHeader>
            <Strong>Output</Strong>
        </DockPaneHeader>
        <DockPaneBody>
            Content 4
        </DockPaneBody>
    </DockPane>
</DockLayout>

Tabbed panes

Panes that share the same tab group can render as tabs. Tool panes usually place tabs at the bottom, while document panes usually place tabs at the top.
<DockLayout Style="height: 24rem;" PaneBordered>
    <DockPane Name="document" Caption="Document" PanePosition="DockPanePosition.Center" Role="DockPaneRole.Document" ShowTab="false" Closable="false">
        <DockPaneHeader>
            <Strong>Document</Strong>
        </DockPaneHeader>
        <DockPaneBody>
            Content 1
        </DockPaneBody>
    </DockPane>

    <DockPane Name="properties" Caption="Properties" PanePosition="DockPanePosition.Right" Size="18rem" TabPosition="DockPaneTabPosition.Bottom" Resizable>
        <DockPaneHeader>
            <Strong>Properties</Strong>
        </DockPaneHeader>
        <DockPaneBody>
            Content 2
        </DockPaneBody>
    </DockPane>

    <DockPane Name="report-explorer" Caption="Report Explorer" PanePosition="DockPanePosition.Right" Size="18rem" TabPosition="DockPaneTabPosition.Bottom" Resizable>
        <DockPaneHeader>
            <Strong>Report Explorer</Strong>
        </DockPaneHeader>
        <DockPaneBody>
            Content 3
        </DockPaneBody>
    </DockPane>
</DockLayout>

State

Use GetState, LoadState, or @bind-State to persist the layout after users move, resize, hide, or activate panes. The returned state can also be edited directly for advanced layouts. Keep pane names stable and call Refresh after changing an assigned state instance in place.
@using System.Text.Json

<DockLayout @ref="@dockLayout" Style="height: 24rem;" PaneBordered>
    <DockPane Name="actions" Caption="Actions" PanePosition="DockPanePosition.Top" Resizable="false" ShowTab="false" AutoHideable="false" Closable="false">
        <DockPaneBody Padding="Padding.Is2">
            <Div Flex="Flex.AlignItems.Center" Gap="Gap.Is2">
                <Button Color="Color.Primary" Size="Size.Small" Clicked="@SaveState">Save state</Button>
                <Button Color="Color.Light" Size="Size.Small" Clicked="@LoadState" Disabled="@(savedStateJson is null)">Load state</Button>
                <Button Color="Color.Light" Size="Size.Small" Clicked="@ResetState">Reset</Button>
                <Text TextColor="TextColor.Secondary">@status</Text>
            </Div>
        </DockPaneBody>
    </DockPane>

    <DockPane Name="source" Caption="Source" PanePosition="DockPanePosition.Left" Size="15rem" MinSize="10rem" Resizable>
        <DockPaneHeader>
            <Strong>Source</Strong>
        </DockPaneHeader>
        <DockPaneBody>
            Content 1
        </DockPaneBody>
    </DockPane>

    <DockPane Name="preview" Caption="Preview" PanePosition="DockPanePosition.Center" Role="DockPaneRole.Document" ShowTab="false" Closable="false">
        <DockPaneHeader>
            <Strong>Preview</Strong>
        </DockPaneHeader>
        <DockPaneBody>
            Content 2
        </DockPaneBody>
    </DockPane>

    <DockPane Name="details" Caption="Details" PanePosition="DockPanePosition.Right" Size="17rem" MinSize="10rem" Resizable>
        <DockPaneHeader>
            <Strong>Details</Strong>
        </DockPaneHeader>
        <DockPaneBody>
            Content 3
        </DockPaneBody>
    </DockPane>
</DockLayout>
@code {
    private DockLayout dockLayout;

    private string savedStateJson;

    private string status = "No saved state.";

    private static JsonSerializerOptions StateSerializerOptions { get; } = new( JsonSerializerDefaults.Web );

    private Task SaveState()
    {
        if ( dockLayout is not null )
        {
            savedStateJson = JsonSerializer.Serialize( dockLayout.GetState(), StateSerializerOptions );
            status = "State saved.";
        }

        return Task.CompletedTask;
    }

    private async Task LoadState()
    {
        if ( dockLayout is not null && savedStateJson is not null )
        {
            DockLayoutState savedState = JsonSerializer.Deserialize<DockLayoutState>( savedStateJson, StateSerializerOptions );

            await dockLayout.LoadState( savedState );
            status = "State loaded.";
        }
    }

    private async Task ResetState()
    {
        if ( dockLayout is not null )
        {
            await dockLayout.ResetState();
            status = "Layout reset.";
        }
    }
}

Best Practices

Useful Workspace

Provide an understandable default arrangement before users begin customizing it. Concise pane headers and practical minimum sizes help every region remain usable after resizing or docking. Small screens may need a simpler responsive arrangement where multi-pane dragging is not required.

Restore State

Give panes stable identities when persisting layout state. A restored layout may have been created before panes were added, removed, or renamed, so handle missing and newly introduced panes without leaving the workspace incomplete.

API

See the API reference for the parameters, events, methods, and related types available to the components covered on this page.

On this page