WebDev Bites: ViewSplitterBar Component Demo

two-panel viewer with draggable splitter and bottom resizer

function greet(name) {
  return `Hello, ${name}!`;
}

const nums = [3, 1, 4, 1, 5, 9];
nums.sort((a, b) => a - b);
console.log(nums.join(', '));
def greet(name):
    return f"Hello, {name}!"

nums = [3, 1, 4, 1, 5, 9]
nums.sort()
print(', '.join(map(str, nums)))
This is a view-splitter-bar component. Drag the vertical bar to redistribute width between panels. Drag the strip at the bottom edge to change the component height. Click either panel to shift the split by one step.
This is the first in a sequence of pages that explore the design of a W3C web component that manages a resizable two-panel view with a draggable splitter. The next page explains the design of the component. The final page shows how an application uses the viewer and lists its public interface.

Component Parts

The primary parts of a web component are:
  1. Class derived from HTMLElement
    Each application of the component's tag creates an instance of this class when the code is parsed at load time.
  2. Shadow DOM, a tree of encapsulated HTML elements
    ViewSplitterBar separates its shadow DOM into two module-level template strings: VSB_STYLE for the CSS and VSB_TEMPLATE for the HTML structure.
    The shadow DOM defines a .container flex row holding .panel-left, a .splitter bar, and .panel-right, plus a .resizer strip below the container for height adjustment.
    Each panel exposes a named slot (slot="left" and slot="right") so the host page supplies content as slotted <pre> or <pre><code> elements.
  3. Event listeners
    Three sets of listeners handle interaction. Splitter drag: mousedown on the splitter bar, then mousemove/mouseup on the document. Resizer drag: mousedown on the resizer strip, then mousemove/mouseup on the document. Panel click: a click on either panel shifts the split by one step-px increment.
    A slotchange listener on each slot applies Prism highlighting and normalizes the box model of newly assigned <pre> elements, then scrolls both panels to the top.
    A ResizeObserver on the host element re-applies the current split ratio whenever the host changes width, keeping the panels correctly proportioned during page resizes.
  4. Helper functions
    ViewSplitterBar uses _getLeftPx(), _setLeftPx(), _availableWidth(), _totalWidthPx(), _getHeightPx(), _setHeightPx(), _applyStyles(), _applyLayout(), _maybePrism(), and _harmonizeSlotted().
  5. Hyphenated tag name associated with the component class.
    The tag name view-splitter-bar is associated with the class ViewSplitterBar.