Docking: header positions
SvDockManager headerPosition: put the tab strip on any side of a panel (top / bottom / left / right - left & right render vertical tabs) and toggle tab reordering.
A live, editable Svelte 5 component example from the SvGrid gallery (Layout). Read the SvGrid UI component docs for the full API.
About this example
SvDockManager header positions in Svelte 5: the tab strip can sit on any side of a panel through headerPosition, top, bottom, left or right, with left and right rendering vertical tabs, and tab reordering can be turned off with reorderEnabled. Dock, float, auto-hide and pop-out keep working in every position.
SvDockManager - header positions + reorder toggle. The tab strip can sit on any side of a panel (top / bottom / left / right - left & right render vertical tabs), and tab reordering can be turned off. Everything else (dock, float, auto-hide, pop-out) still works.
Imports, features and API used
Imports: @svgrid/grid
Frequently asked questions
How do vertical tabs read?
With headerPosition left or right the tab labels rotate along the strip and the active tab connects to the panel, the way IDE side bars do.
Can different panels use different positions?
The prop applies to the manager as a whole so the workspace stays consistent; a per-panel override is not part of this demo.
Why turn reordering off?
For fixed workspaces where tab order carries meaning, or where a drag should always mean dock rather than reorder.
Related documentation
Related articles
- Saved Views - Persist Grid Layout and Filters - Give users named, switchable snapshots of column order, sorting, filters, and grouping - persisted to localStorage or a server adapter - using SvGrid's createNamedViews API.
- Multi-Level (Grouped) Column Headers in SvGrid - Band related columns under a shared parent header using SvGrid's nested column definition - how to nest, pin, combine with sorting and filtering, and when NOT to use grouping.
- A Custom Column Header Menu in SvGrid - Build a per-column header menu for sort, hide, pin, and custom actions using header snippets and your own dropdown component.
Source code (363-dock-headers.svelte)
<script lang="ts">
/**
* SvDockManager - header positions + reorder toggle. The tab strip can sit on
* any side of a panel (top / bottom / left / right - left & right render
* vertical tabs), and tab reordering can be turned off. Everything else (dock,
* float, auto-hide, pop-out) still works.
*/
import { SvDockManager, dockGroup, dockTabs, dockPane, type DockManagerState } from '@svgrid/grid'
let workspace = $state<DockManagerState>({
main: dockGroup('row', [
dockTabs([dockPane('nav', 'Navigator'), dockPane('outline', 'Outline')]),
dockGroup('column', [
dockTabs([dockPane('doc', 'document.ts'), dockPane('styles', 'styles.css')]),
dockTabs([dockPane('console', 'Console'), dockPane('tests', 'Tests')]),
], [0.6, 0.4]),
], [0.28, 0.72]),
floating: [],
autoHide: [],
})
let headerPosition = $state<'top' | 'bottom' | 'left' | 'right'>('top')
let reorderEnabled = $state(true)
</script>
<div class="wrap">
<header>
<h2>Header positions</h2>
<div class="controls">
<span class="lbl">Tab strip:</span>
{#each (['top', 'bottom', 'left', 'right'] as const) as pos (pos)}
<button class="seg" class:on={headerPosition === pos} onclick={() => (headerPosition = pos)}>{pos}</button>
{/each}
<label class="chk"><input type="checkbox" bind:checked={reorderEnabled} /> reorder</label>
</div>
</header>
<div class="stage">
<SvDockManager bind:workspace {headerPosition} {reorderEnabled}>
{#snippet pane(p)}
<div class="panel">
<h3>{p.title}</h3>
<p>Header on the <b>{headerPosition}</b>. Reordering is {reorderEnabled ? 'on' : 'off'}.</p>
</div>
{/snippet}
</SvDockManager>
</div>
</div>
<style>
.wrap { padding: 20px; display: flex; flex-direction: column; gap: 14px; height: 100%; box-sizing: border-box; }
header { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
header h2 { margin: 0; font-size: 20px; font-weight: 700; }
.controls { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.lbl { color: var(--sg-muted, #64748b); font-weight: 600; }
.seg { font: inherit; font-size: 12.5px; font-weight: 600; padding: 4px 12px; text-transform: capitalize; cursor: pointer;
color: var(--sg-fg, #0f172a); background: var(--sg-bg, #fff); border: 1px solid var(--sg-border, #e2e8f0); border-radius: 7px; }
.seg.on { color: var(--sg-on-accent, #fff); background: var(--sg-accent, #2563eb); border-color: var(--sg-accent, #2563eb); }
.chk { display: inline-flex; align-items: center; gap: 5px; margin-inline-start: 8px; color: var(--sg-muted, #64748b); font-weight: 600; }
.stage { flex: 1; min-height: 440px; }
.panel { padding: 16px; font-size: 13px; }
.panel h3 { margin: 0 0 6px; font-size: 14px; }
.panel p { margin: 0; color: var(--sg-muted, #64748b); line-height: 1.6; }
</style>More Layout examples
- Account & security settings console - A real SaaS settings surface composed from the UI kit: SvMenubar app bar, promise + Undo-action toasts on save, SvPopconfirm on destructive rows, SvHoverCard teammate previews, and frame input adornments (leading icons, prefix affixes, masked API key). Profile / Team / Security tabs over SvCard + SvStat.
- Invoice builder - An adornment-heavy money form: currency prefixes, % suffixes, masked tax IDs (frame adornments), line items with SvPopconfirm delete + Undo action toasts, live SvStat totals, an SvHoverCard tax hint, and a promise toast on Send. Pure UI-kit composition.
- Operations KPI dashboard - A KPI console: SvStat + SvSparkline tiles, an SvGauge SLA dial, SvHoverCard drill-down previews per service, an SvMenubar toolbar (View / Range / Actions) and a promise toast on Refresh. Pure UI-kit composition, no grid dependency.
- Form: rich field types - SvForm reaching the whole input suite from one schema - phone, country, mask, combobox, radio, slider, tags, datetime and file - plus per-field help text, a readonly field, column span, and a promise toast on submit.
- Form: cascading fields - SvForm dependent selects - a child list derives from the parent value via a function `options`, and `dependsOn` clears the child when the parent changes so a stale selection never lingers. Country -> State -> City.