Split Pane

Resizable panels with draggable divider, using data-bind-style.

Live Demo

Editor

Drag the handle to resize panels.

Left width: px

Preview

This panel fills the remaining space.

Source

HTML + JavaScript
<div data-component="split-pane">
    <div class="split-container">
        <div class="split-left"
             data-bind-style="{ width: leftWidth + 'px' }">
            <p>Left panel</p>
        </div>
        <div class="split-handle"
             data-action="mousedown:startResize"></div>
        <div class="split-right">
            <p>Right panel (flex: 1)</p>
        </div>
    </div>
</div>

<script>
wildflower.component('split-pane', {
    state: { leftWidth: 250, dragging: false },
    startResize(e) {
        this.dragging = true;
        const onMove = (ev) => {
            const container = document.getElementById('split-demo-container');
            const rect = container.getBoundingClientRect();
            const x = ev.clientX - rect.left;
            this.leftWidth = Math.max(100, Math.min(x, rect.width - 100));
        };
        const onUp = () => {
            this.dragging = false;
            document.removeEventListener('mousemove', onMove);
            document.removeEventListener('mouseup', onUp);
        };
        document.addEventListener('mousemove', onMove);
        document.addEventListener('mouseup', onUp);
    }
});
</script>

Key Points

  • data-bind-style="{ width: leftWidth + 'px' }" reactively sets the panel width from state
  • data-action="mousedown:startResize" initiates drag on the handle. Mousemove/mouseup are added to document so dragging works even outside the handle
  • State updates during mousemove are batched, giving smooth resizing without layout thrash
  • The right panel uses flex: 1 to automatically fill the remaining space