A creative workspace
This is the JavaScript used by the first playground preset. Edit and run it in the interactive playground, including its HTML and CSS.
import { DockingManager, LayoutRoot, LayoutPanel, LayoutDocumentPane,
LayoutAnchorablePane, LayoutDocument, LayoutAnchorable,
XmlLayoutSerializer } from '@wieslawsoltes/dockyard';
const editor = document.createElement('textarea');
editor.setAttribute('aria-label', 'Workspace notes');
editor.value = 'A workspace that moves with you.\n\nDrag this tab. Float it. Bring it home.\nYour notes stay right here.';
editor.style.cssText = 'width:100%;height:100%;box-sizing:border-box';
const tools = document.createElement('div');
tools.innerHTML = '<div class="panel"><h2>Explorer</h2><p>▧ Project brief</p><p>▤ Design notes</p><p>◇ Components</p><hr><p class="hint">Your real DOM content, retained.</p></div>';
const doc = new LayoutDocument({ContentId:'notes', Title:'Project notes', Content:editor});
const tool = new LayoutAnchorable({ContentId:'explorer', Title:'Explorer', Content:tools});
const manager = new DockingManager(document.querySelector('#workspace'), {
Theme: document.documentElement.dataset.theme,
Layout: new LayoutRoot({RootPanel:new LayoutPanel({Orientation:'Horizontal', Children:[
new LayoutAnchorablePane({DockWidth:190,Children:[tool]}),
new LayoutDocumentPane({Children:[doc]})
]})})
});
const serializer = new XmlLayoutSerializer(manager);
let saved = serializer.Serialize();
document.querySelector('#float').onclick=()=>manager.Find('notes').Float();
document.querySelector('#dock').onclick=()=>manager.Find('notes').Dock();
document.querySelector('#hide').onclick=()=>manager.Find('explorer').ToggleAutoHide();
document.querySelector('#save').onclick=()=>{saved=serializer.Serialize();console.log('Layout captured',saved.length,'characters');};
document.querySelector('#restore').onclick=()=>{serializer.Deserialize(saved);console.log('Layout restored');};
window.addEventListener('pagehide',()=>manager.Dispose());
console.log('Dockyard ready: drag a tab or try Float editor.');Show the HTML host
<div class="toolbar"><button id="float">Float editor</button><button id="dock">Dock editor</button><button id="hide">Auto-hide tools</button><button id="save">Save layout</button><button id="restore">Restore</button></div><div id="workspace" class="stage"></div><p class="hint">Drag tabs, resize splitters and edit the note. The content stays alive as you move it.</p>How it works
Layout is a living model
Documents, tools and split panes share one observable layout tree. Move the real DOM content, not screenshots of it.
Import the stylesheet and give the host a measurable height before creating a DockingManager. Keep stable ContentId values when saving layouts.
Own the lifetime
Call manager.Dispose() when the host is removed. Resolve restored content by ContentId because deserialization recreates model wrappers.
The playground replaces its entire isolated frame on each run. In your application, use the framework’s unmount or disposal hook instead. Do not dispose a shared model while another view still owns it.
Read the lifecycle guide →Know the contract
Source repositories can contain work newer than the published package. The showcase uses @wieslawsoltes/dockyard@0.2.0.