WebDev ViewComparator Component

side-by-side panels with draggable splitter for comparing code or text

1.0 Contents

A W3C custom element (<view-comparator>) that displays two side-by-side panels separated by a draggable splitter bar. Designed for comparing code or text across languages, versions, or styles.

2.0 Files

ViewComparatorComponent/
  js/
    ViewComparator.js           component definition
  css/
    ViewComparator.css          host-page placement helpers
  ViewComparatorComponent.html  demo / test page
  SpecComparatorComponent.md    detailed specification
  README.md                     this file

3.0 Usage


#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>

int main() {
    std::vector<int> v = {5, 3, 8, 1, 9, 2, 7};

    std::sort(v.begin(), v.end());

    int sum = std::accumulate(v.begin(), v.end(), 0);
    double avg = static_cast<double>(sum) / v.size();

    std::cout << "sorted: ";
    for (int x : v) std::cout << x << " ";
    std::cout << "\nsum = " << sum
              << "  avg = " << avg << "\n";
    return 0;
}
    

fn main() {
    let mut v = vec![5, 3, 8, 1, 9, 2, 7];

    v.sort();

    let sum: i32 = v.iter().sum();
    let avg = sum as f64 / v.len() as f64;

    print!("sorted: ");
    for x in &v { print!("{x} "); }
    println!("\nsum = {sum}  avg = {avg}");
}
    

Place in host page header:

<link rel="stylesheet" href="css/ViewComparator.css">
<script src="js/ViewComparator.js" defer></script>

Place in body

Plain text in both panels:

<view-comparator width="min(60rem, 100%)" height="20rem" left-ratio="0.5">
  <pre slot="left">Left panel content.</pre>
  <pre slot="right">Right panel content.</pre>
</view-comparator>

Code With Prism syntax highlighting:

<view-comparator width="min(70rem, 100%)" height="24rem" highlight="prism" left-ratio="0.5">
  <pre slot="left"><code class="language-cpp">// C++ code</code></pre>
  <pre slot="right"><code class="language-rust">// Rust code</code></pre>
</view-comparator>

4.0 Attributes

AttributeDefaultDescription
widthautoTotal component width; supports CSS functions, e.g. min(70rem, 100%)
heightautoPanel height
left-ratio0.5Initial fraction of width given to the left panel
bar-width6pxWidth of the splitter bar
bar-color#888Color of the splitter bar
bg-colorvar(--light)Background of both panels
colorvar(--dark)Foreground (text) color of both panels
overflow-xautoHorizontal overflow: auto, scroll, or hidden
code-padding0.75rem 1remPadding inside each panel
highlight(none)Set to prism to enable Prism.js highlighting
step-px40Pixels transferred per panel-click width adjustment
min-panel-px120Minimum width in pixels for either panel
min-height-px80Minimum height in pixels
offset-step-px40Pixels shifted per right-panel offset action
font-size0.9remFont size for code in both panels

5.0 Behavior

  • Both panels scroll to the top when the component connects to the page.
  • The initial split ratio is reapplied automatically when the browser window is resized.

6.0 Interactions

Panel width
  • Drag the splitter bar left or right to redistribute width between panels.
  • Click the left panel to grow it by step-px; click the right panel to grow it.
Component height
  • Drag the resizer strip at the bottom edge to change the component height.
Right-panel vertical offset
When comparing content of unequal length, the right panel's content can be shifted down to align specific lines with the left panel. Space added above the content inherits the content's own background color.
ActionEffect
Click buttonShift right content down by offset-step-px
Click buttonShift right content up by offset-step-px
Click 0 buttonReset offset to zero
Alt+↓ (right panel focused)Same as ▼
Alt+↑ (right panel focused)Same as ▲
Escape (right panel focused)Same as 0
The ▲ 0 ▼ buttons appear near the top-right corner of the right panel. They are faint until hovered or until the right panel has focus (click anywhere in it).

7.0 Dependencies

  • Prism.js - optional; required only when highlight="prism" is set. Load prism.js and prism.css before the component script.
  • No other runtime dependencies.