Diff
Since 0.1.0-alpha.20Static server-side rendering: no circuit, no WebAssembly.
Usage
<Diff OldText="older.Xml" NewText="newer.Xml" Language="xml" Title="v3 → v4" />
<Diff OldText="before" NewText="after" Language="csharp" Layout="DiffLayout.Split" />The diff is computed and colored on the server, so it looks the same with JavaScript off. Lines removed and added carry a − or + and their old or new line number; the numbers and signs aren't copied when you select the lines.
Two versions
Use OldText and NewText for the two texts and Language to color them; unchanged lines away from the changes fold.
Preview
9 unchanged lines
Code
<Diff OldText="V3" NewText="V4" Language="xml" Title="v3 → v4" />Each text is colored whole before it's cut into lines, so a comment or value across several lines keeps its color. In a removed line beside an added one, the changed words are marked, unless less than half of the longer line is unchanged (MarkWords turns this off). Context sets how many unchanged lines stay beside each change (3); the rest fold into a row that opens them in place.
Side by side
Use Layout DiffLayout.Split to put the old text beside the new; below 45rem wide it shows as unified.
Preview
3 unchanged lines
Code
<Diff OldText="Before" NewText="After" Language="csharp" Title="OrderTotals.cs" Layout="DiffLayout.Split" />Each removed line sits beside the line it became, and long lines wrap rather than scroll. Unchanged lines are drawn on both sides, so a split diff sends them twice.
Every line
Use Fold="false" to show every unchanged line and LineNumbers="false" to leave the numbers out, for a short text.
Preview
Code
<Diff OldText="Before" NewText="After" Language="json" Fold="false" LineNumbers="false" />A diff computed first
Use Lines for a diff you computed with TextDiff.Compare or elsewhere, such as to count the changes first.
Preview
Release notes
2 added 1 removedCode
{
// Null when the texts differ by more lines than Compare looks for.
var lines = TextDiff.Compare(Before, After);
}
<Column Gap="3">
<Row Gap="2" Align="Align.Center">
<TextBlock Weight="FontWeight.Medium">Release notes</TextBlock>
if (lines is not null)
{
<Badge Status="Status.Success">lines.Count(l => l.Kind == DiffKind.Added) added</Badge>
<Badge Status="Status.Danger">lines.Count(l => l.Kind == DiffKind.Removed) removed</Badge>
}
</Row>
if (lines is not null)
{
<Diff Lines="lines" />
}
else
{
<TextBlock>Too many changes to show.</TextBlock>
}
</Column>TextDiff.Compare(oldText, newText) returns every line of both texts as a DiffLine (its Kind, OldNumber, NewNumber and Text), or null when they differ by more lines than it looks for. Lines from elsewhere should be every line of both texts, in order, removed lines before the added lines that replace them.
No changes, or too many
Use SameText and TooManyText to change the notes shown when the texts are the same, or differ by more than MaxChanges lines.
Preview
The two texts are the same.
The texts differ by more than 2 lines, too many to show line by line.
Code
<Column Gap="4">
<Diff OldText="Text" NewText="Text" Title="settings.json" />
<Diff OldText="Text" NewText="Other" MaxChanges="2" Title="settings.json" />
</Column>Large texts
The lines both texts start and end with cost nothing; past them, the comparison's work grows with the length of the rest times the lines that differ, and MaxChanges (1,000 lines removed and added) bounds it. Folded lines are still in the page, ready to open, so a 5,000-line file with one change sends 5,000 lines; set MaxHeight to keep a long diff in a scrolling box.
Mode support
| Feature | Static | Interactive |
|---|---|---|
| Lines removed and added, with old and new numbers | Yes | Yes |
| Changed words marked, colored as Code colors them | Yes | Yes |
| Unchanged runs folded, opened in place | Yes | Yes |
| Side by side, unified when narrow | Yes | Yes |
Static: static server-side rendering, with no circuit and no WebAssembly. Interactive: Server, WebAssembly or Auto.
Accessibility
- The lines are a tab stop, so they can be scrolled from the keyboard: a group named by
Title, or "Changes" without one, described by the counts ("3 added, 1 removed"). - Each removed or added line starts with "Removed:" or "Added:" for screen readers; the visible
+and−, the line numbers and that text aren't copied with the lines. - Colors aren't the only mark: removed and added lines have their sign, also in forced colors.
- A folded run is a
summary, opened with Enter or Space, read as collapsed or expanded. - In Split, unchanged lines are read once (the old side's copy is hidden from screen readers).
Parameters
| Prop | Type | Default |
|---|---|---|
OldTextThe old text. | string? | |
NewTextThe new text. | string? | |
LinesA diff computed elsewhere, such as by Compare, in place of OldText and NewText: every line of both texts, in order. | IReadOnlyList<DiffLine>? | |
LanguageThe language, such as "xml", "csharp" or "json": colors the lines as Code does, when the highlighter knows it (see Languages). | string? | |
HighlightColors the lines by Language. | bool | true |
TitleA file name or caption, such as "rules.xml" or "v3 → v4", in a header row above the lines. | string? | |
LayoutDiffLayout.Unified (the default): one column, removed lines before added. | DiffLayout | DiffLayout.Unified |
ContextThe unchanged lines kept on each side of a change when the rest are folded. | int | 3 |
FoldFolds runs of unchanged lines away from the changes into a row that opens them. | bool | true |
MarkWordsMarks the changed words of a removed line and the added line paired with it. | bool | true |
LineNumbersShows the old and new line numbers. | bool | true |
MaxHeightThe tallest the lines get before they scroll, such as Length.Rem(30). | Length? | |
MaxChangesThe most lines removed and added to look for. | int | 1000 |
SameTextShown when the two texts are the same. | string? | |
TooManyTextShown when the texts differ by more than MaxChanges lines. | string? |
Plus 16 item props and 4 common props.
Full APISee also
- Code: inline code or a block, highlighted on the server.
- Demos: Version history.