Skip to content

Code Comparison

Two code panels, before and after, side by side on wider screens and stacked on phones. Each has a label, line numbers and optional highlighted lines. It does no syntax colouring and has no dependency.

Motionv0.1.0experimentalWCAG 2.2 AAView spec

Optional, and kept apart.

Nothing here is included in a project unless you add it, and the plain component it builds on is unchanged. This effect is decoration: it is hidden from screen readers, stands still for visitors who prefer reduced motion, and can be paused. Use Still on a preview to see that version.

Before (javascript)
function total(items) {  let sum = 0;  for (const item of items) {    sum += item.price;  }  return sum;}
After (javascript)
function total(items) {  return items.reduce((sum, item) => sum + item.price, 0);}
import { CodeComparison } from "@rdloom/react";

const before = `function total(items) {
  let sum = 0;
  for (const item of items) {
    sum += item.price;
  }
  return sum;
}`;

const after = `function total(items) {
  return items.reduce((sum, item) => sum + item.price, 0);
}`;

export default function CodeComparisonBasicExample() {
  return (
    <div className="flex w-full justify-center">
      <CodeComparison className="w-full max-w-5xl" before={before} after={after} language="javascript" />
    </div>
  );
}

Installation

npx rdloom add code-comparison

Copies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes.

Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/code-comparison.json

Works, but without upgrade tracking.

Usage

import { CodeComparison } from "@rdloom/react";

<div className="flex w-full justify-center">
  <CodeComparison className="w-full max-w-5xl" before={before} after={after} language="javascript" />
</div>

With highlights

Plain element. Highlighted lines: 1
<button onClick={save}>  Save</button>
Library button. Highlighted lines: 1
<Button onPress={save}>  Save</Button>
import { CodeComparison } from "@rdloom/react";

const before = `<button onClick={save}>
  Save
</button>`;

const after = `<Button onPress={save}>
  Save
</Button>`;

export default function CodeComparisonWithHighlightsExample() {
  return (
    <div className="flex w-full justify-center">
      <CodeComparison
        className="w-full max-w-5xl"
        label="Button migration"
        beforeLabel="Plain element"
        afterLabel="Library button"
        before={before}
        after={after}
        beforeHighlight={[1]}
        afterHighlight={[1]}
      />
    </div>
  );
}

API Reference

Defined by the spec. Components also accept the props of the React Aria component they wrap.

PropTypeDefault
beforerequired

The code shown in the first panel.

stringnone
afterrequired

The code shown in the second panel.

stringnone
beforeLabel

Caption of the first panel.

string"Before"
afterLabel

Caption of the second panel.

string"After"
beforeHighlight

Line numbers (starting at 1) to mark in the first panel.

number[]none
afterHighlight

Line numbers (starting at 1) to mark in the second panel.

number[]none
label

Accessible name of the whole comparison.

string"Code comparison"
language

Language name, shown in the caption and used as a data attribute. No colouring is applied.

stringnone

Accessibility

Role group, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.

Keyboard

  • Tab: moves to each code area, which scrolls with the arrow keys when a line is wide

Screen readers announce

  • Group, then each figure with its caption, the highlighted line numbers, then the code

What your code must do

  • The comparison is a group named by label; each panel is a figure with a caption
  • The code is real text in pre and code, in the server HTML, with no JavaScript needed
  • Highlighted lines are marked by a bar and a tint, not by colour alone, and the caption lists them in text for screen readers
  • Line numbers are decoration and are not read or copied
  • Panels stack on phones and sit side by side from the medium breakpoint, and the page never scrolls sideways
  • No motion

Guidelines

Use it when

  • Showing a migration or a fix as before and after
  • Docs that compare two ways to write the same thing

Avoid it when

  • A line-by-line diff of real files (use a diff tool)
  • Code that needs syntax colouring

Don't

  • Highlighting most of the lines
  • Comparing code in different languages

Design tokens

The semantic tokens this component uses. Change them once and every component follows; see Design tokens.

  • --rd-color-surface-subtle
  • --rd-color-border-default
  • --rd-color-text-default
  • --rd-color-text-muted
  • --rd-color-action-primary
  • --rd-color-focus-ring
  • --rd-radius-control