Diff Viewer
oge-diff-viewer compares two texts — or two JSON documents — side by side or inline.
A Myers line diff with the changed words highlighted inside changed lines; unchanged runs fold around each change and open on a click. JSON is compared as canonical, key-sorted text, so key order never counts as a change, and the changed paths come back as a list. The toolbar counts what was added and removed, switches the layout and steps through the changes; every changed line says “Added” or “Removed” to a screen reader, not only by colour.
Text
Two versions of a config file: the changed values are highlighted word by word, the unchanged block between the changes folds to one line of context each side. Switch to Inline for one column, or step through the changes with the toolbar.
| Before | After | ||
|---|---|---|---|
| 1 | server: | 1 | server: |
| 2 | host: 0.0.0.0 | 2 | host: 0.0.0.0 |
| 3 | Removed: port: 8080 | 3 | Added: port: 8443 |
| 4 | Removed: workers: 4 | 4 | Added: workers: 8 |
| 5 | Added: tls: true | ||
| 5 | logging: | 6 | logging: |
| 6 | Removed: level: info | 7 | Added: level: warn |
| 7 | format: json | 8 | format: json |
| 13 | export: true | 14 | export: true |
| 14 | Removed: beta-dashboard: false | ||
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { OgeDiffViewer } from '@oge-ui/layout';
@Component({
selector: 'demo-root',
imports: [OgeDiffViewer],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<!-- Changed words are highlighted inside changed lines; unchanged runs fold
to [context] lines around each change. -->
<oge-diff-viewer [oldValue]="before" [newValue]="after" [context]="1" [(mode)]="mode" />
`,
})
export class Demo {
protected readonly mode = signal<'split' | 'inline'>('split');
protected readonly before = 'server:\n port: 8080\n workers: 4\nlogging:\n level: info';
protected readonly after = 'server:\n port: 8443\n workers: 8\n tls: true\nlogging:\n level: warn';
}JSON
JSON text on one side and a value on the other, its keys in another order: only the real changes show, and diff().changes lists their paths.
| Before | After | Comparison |
|---|---|---|
| 1 | 1 | { |
| 2 | 2 | "name": "Desk lamp", |
| 3 | Removed: "price": 39.9, | |
| 3 | Added: "price": 34.9, | |
| 4 | 4 | "sku": "SKU-2041", |
| 5 | 5 | "stock": { |
| 6 | 6 | "store": 8, |
| 7 | Removed: "warehouse": 120 | |
| 7 | Added: "warehouse": 96 | |
| 8 | 8 | }, |
| 9 | 9 | "tags": [ |
| 10 | 10 | "lighting", |
| 11 | Removed: "office" | |
| 11 | Added: "office", | |
| 12 | Added: "sale" | |
| 12 | 13 | ] |
| 13 | 14 | } |
- changed $.price
- changed $.stock.warehouse
- added $.tags[2]
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { OgeDiffViewer } from '@oge-ui/layout';
@Component({
selector: 'demo-root',
imports: [OgeDiffViewer],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<!-- JSON text or values, compared as canonical key-sorted text: the key
order is not a change. diff().changes lists the changed paths. -->
<oge-diff-viewer #viewer language="json" [oldValue]="before" [newValue]="after" mode="inline" />
<ul>
@for (change of viewer.diff().changes; track change.path) {
<li>{{ change.kind }} {{ change.path }}</li>
}
</ul>
`,
})
export class Demo {
protected readonly before = '{"sku": "SKU-2041", "price": 39.9, "tags": ["lighting"]}';
protected readonly after = { price: 34.9, sku: 'SKU-2041', tags: ['lighting', 'sale'] };
}