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.
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.
function total(items) { let sum = 0; for (const item of items) { sum += item.price; } return sum;}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-comparisonCopies 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.jsonWorks, 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
<button onClick={save}> Save</button><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.
| Prop | Type | Default |
|---|---|---|
beforerequiredThe code shown in the first panel. | string | none |
afterrequiredThe code shown in the second panel. | string | none |
beforeLabelCaption of the first panel. | string | "Before" |
afterLabelCaption of the second panel. | string | "After" |
beforeHighlightLine numbers (starting at 1) to mark in the first panel. | number[] | none |
afterHighlightLine numbers (starting at 1) to mark in the second panel. | number[] | none |
labelAccessible name of the whole comparison. | string | "Code comparison" |
languageLanguage name, shown in the caption and used as a data attribute. No colouring is applied. | string | none |
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