WebDev Bites: TwoPanelViewer Component Demo

index-based two-panel navigator with external toolbar controls

Template Literals

Template literals use backtick delimiters and embed expressions with ${...}. They support multi-line strings without escape sequences.

Arrow Functions

Arrow functions provide concise syntax and inherit this from the enclosing scope. Single-expression bodies return implicitly; object literals require parentheses.

Destructuring

Destructuring extracts values from arrays or properties from objects into distinct variables. Rest syntax collects remaining items; default values handle absent properties.

Async / Await

async functions always return a Promise. await suspends execution until the awaited Promise settles, allowing sequential-style code over asynchronous operations.
const name = 'World';
const msg  = `Hello, ${name}!`;

const multiLine = `
  line one
  line two
`;

const expr = `sum = ${2 + 3}`; // "sum = 5"
const double = x => x * 2;
const add    = (a, b) => a + b;

// implicit object return requires parens
const pair   = x => ({ value: x, label: String(x) });

const nums = [1, 2, 3];
const doubled = nums.map(x => x * 2); // [2, 4, 6]
// array destructuring
const [first, second, ...rest] = [10, 20, 30, 40];

// object destructuring with rename and default
const { x: px = 0, y: py = 0 } = { x: 5 };

// in function parameter
function greet({ name = 'stranger', age }) {
  return `${name} is ${age}`;
}
async function fetchUser(id) {
  const res  = await fetch(`/api/users/${id}`);
  if (!res.ok) throw new Error(res.statusText);
  return res.json();
}

// calling
const user = await fetchUser(42);
console.log(user.name);
This is an x-two-panel component. The toolbar buttons Narrow and Widen resize the left panel. Toggle Left hides or restores it. Prev and Next navigate between paired left-right items by index - each click shows the next description and its corresponding code block. Reset returns the panel width to its initial value.
This is the first in a sequence of pages that explore the design of a W3C web component that manages a navigable two-panel view with external toolbar controls. 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. XTwoPanel uses a constructor-function pattern with Reflect.construct rather than class syntax, making it compatible with non-module script loading.
  2. Shadow DOM, a tree of encapsulated HTML elements
    The shadow DOM is a CSS grid (.wrap) containing two panel sections. .panel.left and .panel.right each hold a .scroller div that wraps the named slot. CSS custom properties (--two-gap, --two-height, --two-left) drive the grid layout so attribute changes update the view without touching the shadow stylesheet directly.
    When the left attribute is set, the host gets data-left-fixed which switches the grid to a fixed-plus-fill layout. The collapsed-left attribute hides the left column entirely.
  3. Index-based array navigation
    On connect, the component collects matching left items (default selector .left-item) and right items (default .right-item) into two parallel arrays. Only the pair at the current index is visible; all others have display:none. Prev/Next increment or decrement the index and re-render.
    Custom selectors via data-desc-selector and data-right-selector let the host page use any element class for pairs.
  4. External controls
    A single document-level click listener (installed once at load time) intercepts any button with a data-two attribute and routes it to the nearest x-two-panel identified by data-two-for. Actions include narrow, widen, toggle-left, reset, collapse-left, expand-left, next, and prev. A second IIFE auto-disables Prev/Next buttons at the array boundaries by listening to the two:nav custom event.
  5. Hyphenated tag name associated with the component class.
    The tag name x-two-panel is associated with the class XTwoPanel.