Skip to content

Commit 9432ff2

Browse files
committed
docs: rewrite README with comprehensive documentation
- Complete rewrite with all component parameters documented - Add 'How Character Highlighting Works' section explaining word+character two-tier highlighting approach - Add full CSS custom properties reference (22 variables) - Add complete CSS classes reference for all diff states - Add highlight shape customization examples - Add AI-Assisted Development transparency section - Add dark mode and theming documentation
1 parent e019bf3 commit 9432ff2

File tree

1 file changed

+172
-113
lines changed

1 file changed

+172
-113
lines changed

README.md

Lines changed: 172 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,167 +1,226 @@
1-
# BlazorTextDiff 🔍
1+
# BlazorTextDiff
22

3-
A modern Blazor component for displaying side-by-side text differences with syntax highlighting and advanced comparison features. Built on top of the powerful [DiffPlex](https://github.com/mmanela/diffplex) library.
3+
A Blazor component for displaying side-by-side text differences with character-level highlighting. Built on [DiffPlex](https://github.com/mmanela/diffplex).
44

5-
## 🚀 Features
5+
## Features
66

7-
- **Side-by-side comparison** with clear visual indicators
8-
- **Syntax highlighting** for better readability
9-
- **Ignore case and whitespace** options
10-
- **Async diff processing** for large texts
11-
- **Customizable headers** with diff statistics
12-
- **Responsive design** that works on all devices
13-
- **Easy integration** with existing Blazor applications
7+
- Side-by-side diff with line numbers
8+
- Character-level highlighting within changed lines
9+
- Word-level soft highlight with character-level strong highlight for partial changes
10+
- Adjacent character highlights merge into smooth pill shapes
11+
- Collapse/expand unchanged sections
12+
- Ignore case and whitespace options
13+
- Custom header with diff statistics
14+
- Custom CSS class and attribute support
15+
- Fully themeable via CSS custom properties
16+
- Dark mode via `prefers-color-scheme`
17+
- Responsive and accessible
1418

15-
## 📊 Status
19+
## Status
1620

1721
[![Build and Publish Packages](https://github.com/lzinga/BlazorTextDiff/actions/workflows/publish-packages.yml/badge.svg)](https://github.com/lzinga/BlazorTextDiff/actions/workflows/publish-packages.yml)
1822
[![Deploy to GitHub Pages](https://github.com/lzinga/BlazorTextDiff/actions/workflows/deploy-pages.yml/badge.svg)](https://github.com/lzinga/BlazorTextDiff/actions/workflows/deploy-pages.yml)
1923
[![NuGet](https://img.shields.io/nuget/v/BlazorTextDiff.svg)](https://www.nuget.org/packages/BlazorTextDiff/)
20-
[![NuGet Downloads](https://img.shields.io/nuget/dt/BlazorTextDiff.svg)](https://www.nuget.org/packages/BlazorTextDiff/)
2124

22-
## 🎮 Live Demo
25+
## Live Demo
2326

24-
Try the interactive demo: [https://lzinga.github.io/BlazorTextDiff/](https://lzinga.github.io/BlazorTextDiff/)
27+
[https://lzinga.github.io/BlazorTextDiff/](https://lzinga.github.io/BlazorTextDiff/)
2528

26-
## 📸 Screenshots
29+
## Installation
2730

28-
![Static Diff](https://i.imgur.com/t0nJPeZ.png)
29-
*Basic text comparison showing additions, deletions, and modifications*
31+
```bash
32+
dotnet add package BlazorTextDiff
33+
```
3034

31-
![Async Diff](https://i.imgur.com/lzjfjhF.png)
32-
*Async processing for large text comparisons*
35+
## Setup
3336

34-
## 📦 Installation
37+
Add the stylesheet to your `index.html` or `_Host.cshtml`:
3538

36-
Install the NuGet package:
39+
```html
40+
<link href="_content/BlazorTextDiff/css/BlazorDiff.css" rel="stylesheet" />
41+
```
3742

38-
```bash
39-
dotnet add package BlazorTextDiff
43+
No JavaScript or service registration is required.
44+
45+
## Usage
46+
47+
### Basic
48+
49+
```razor
50+
<TextDiff OldText="@oldText" NewText="@newText" />
4051
```
4152

42-
You'll also need the DiffPlex library:
53+
### With Options
4354

44-
```bash
45-
dotnet add package DiffPlex
55+
```razor
56+
<TextDiff OldText="@oldText"
57+
NewText="@newText"
58+
CollapseContent="true"
59+
IgnoreCase="true"
60+
IgnoreWhiteSpace="false"
61+
Class="my-diff">
62+
<Header>
63+
<div style="padding: 10px 12px;">
64+
<span class="diff-stats-badge warning">@context.LineModificationCount modified</span>
65+
<span class="diff-stats-badge danger">@context.LineDeletionCount deleted</span>
66+
<span class="diff-stats-badge success">@context.LineAdditionCount added</span>
67+
</div>
68+
</Header>
69+
</TextDiff>
4670
```
4771

48-
## ⚙️ Setup
72+
## Parameters
73+
74+
| Parameter | Type | Default | Description |
75+
|---|---|---|---|
76+
| `OldText` | `string?` | `null` | Original text (left pane) |
77+
| `NewText` | `string?` | `null` | Modified text (right pane) |
78+
| `CollapseContent` | `bool` | `false` | Collapse unchanged sections |
79+
| `MaxHeight` | `int` | `300` | Max height (px) when collapsed |
80+
| `IgnoreCase` | `bool` | `false` | Ignore case differences |
81+
| `IgnoreWhiteSpace` | `bool` | `false` | Ignore whitespace differences |
82+
| `Header` | `RenderFragment<DiffStats>?` | `null` | Custom header template |
83+
| `Class` | `string?` | `null` | Additional CSS class(es) |
84+
85+
Unmatched HTML attributes (`style`, `id`, `data-*`, etc.) are passed through to the root element.
86+
87+
## How Character Highlighting Works
88+
89+
The component uses three levels of visual hierarchy:
90+
91+
1. **Line-level** — the entire row gets a colored background (`inserted-line`, `deleted-line`, `modified-line`)
92+
2. **Word-level** — when a word is partially changed, it gets a soft background highlight (`inserted-word`, `deleted-word`, `modified-word`)
93+
3. **Character-level** — the specific changed characters get a strong highlight (`inserted-character`, `deleted-character`, `modified-character`)
94+
95+
For example, `Programing``Programming`:
96+
- The whole word wraps in `<span class="inserted-word">` (soft green background)
97+
- Only the added `m` wraps in `<span class="inserted-character">` (strong green highlight)
4998

50-
### 1. Configure Services
99+
When a word is entirely changed (e.g. `cat``dog`), it skips the word wrapper and uses the character-level class directly.
51100

52-
Add the required services to your `Program.cs`:
101+
Adjacent character highlights automatically merge into a single pill shape — rounded corners only appear on the first and last character in a run.
53102

54-
```csharp
55-
// Program.cs
56-
public static async Task Main(string[] args)
57-
{
58-
var builder = WebAssemblyHostBuilder.CreateDefault(args);
59-
60-
// Register BlazorTextDiff dependencies
61-
builder.Services.AddScoped<ISideBySideDiffBuilder, SideBySideDiffBuilder>();
62-
builder.Services.AddScoped<IDiffer, Differ>();
103+
## Customization
63104

64-
builder.RootComponents.Add<App>("app");
105+
All visual styling is controlled via CSS custom properties. Override them in your own stylesheet to retheme the component.
65106

66-
await builder.Build().RunAsync();
107+
### Diff Colors
108+
109+
```css
110+
:root {
111+
/* Line-level backgrounds */
112+
--diff-addition-bg: #e6ffed;
113+
--diff-deletion-bg: #ffeef0;
114+
--diff-modification-bg: #fff8c5;
115+
116+
/* Line-level left border accents */
117+
--diff-addition-border: #2ea043;
118+
--diff-deletion-border: #f85149;
119+
--diff-modification-border: #fb8500;
120+
121+
/* Character-level strong highlights */
122+
--diff-addition-highlight: #7ce89b;
123+
--diff-deletion-highlight: #f9a8b0;
124+
--diff-modification-highlight: #ffc833;
67125
}
68126
```
69127

70-
### 2. Include Styles and Scripts
128+
The word-level soft background reuses `--diff-*-bg` (same as the line), and the character-level strong highlight uses `--diff-*-highlight`.
71129

72-
Add to your `index.html` or `_Host.cshtml`:
130+
### Highlight Shape
73131

74-
```html
75-
<!-- Required CSS -->
76-
<link href="_content/BlazorTextDiff/css/BlazorDiff.css" rel="stylesheet" />
77-
78-
<!-- Required JavaScript -->
79-
<script src="_content/BlazorTextDiff/js/BlazorTextDiff.js"></script>
132+
```css
133+
:root {
134+
/* Character highlight pill shape */
135+
--diff-char-radius: 3px; /* border-radius for each character span */
136+
--diff-char-padding: 1px 2px; /* padding inside each character span */
137+
138+
/* Word highlight shape */
139+
--diff-word-radius: 3px; /* border-radius for the word wrapper */
140+
--diff-word-padding: 1px 0; /* padding inside the word wrapper */
141+
}
80142
```
81143

82-
## 🎯 Usage
144+
Examples:
83145

84-
### Basic Comparison
146+
```css
147+
/* Sharp rectangles instead of rounded pills */
148+
:root { --diff-char-radius: 0; --diff-word-radius: 0; }
85149

86-
```html
87-
<TextDiff OldText="@oldText" NewText="@newText" />
150+
/* Larger, more prominent pills */
151+
:root { --diff-char-radius: 6px; --diff-char-padding: 2px 4px; }
152+
153+
/* Underline style (no background, border-bottom instead) */
154+
.my-diff .inserted-character { background: none; border-bottom: 2px solid #2ea043; }
155+
.my-diff .deleted-character { background: none; border-bottom: 2px solid #f85149; text-decoration: line-through; }
88156
```
89157

90-
### Advanced Features
158+
### Scoped Overrides
91159

92-
```html
93-
<TextDiff
94-
OldText="@oldText"
95-
NewText="@newText"
96-
CollapseContent="true"
97-
ShowWhiteSpace="true"
98-
IgnoreCase="true"
99-
IgnoreWhiteSpace="false">
100-
101-
<Header>
102-
<div class="diff-stats">
103-
<span class="badge bg-success">+@context.LineAdditionCount</span>
104-
<span class="badge bg-warning">~@context.LineModificationCount</span>
105-
<span class="badge bg-danger">-@context.LineDeletionCount</span>
106-
</div>
107-
</Header>
108-
</TextDiff>
160+
Use the `Class` parameter to scope styles to a specific instance:
161+
162+
```css
163+
.my-diff .modified-line { background-color: #ffe0b2; }
164+
.my-diff .deleted-character { background-color: #e53935; color: #fff; }
109165
```
110166

111-
### Async Processing
167+
### CSS Classes Reference
112168

113-
For large texts, use async processing:
169+
**Layout:**
170+
`diff-container`, `diff-pane-left`, `diff-pane-right`, `diff-header`, `diff-panes`, `diff-expand-notice`
114171

115-
```csharp
116-
@code {
117-
private string oldText = "";
118-
private string newText = "";
119-
private bool isProcessing = false;
172+
**Line-level (on `<td>`):**
173+
`inserted-line`, `deleted-line`, `modified-line`, `unchanged-line`
120174

121-
private async Task ProcessLargeDiff()
122-
{
123-
isProcessing = true;
124-
// Your async logic here
125-
await Task.Delay(100); // Simulate processing
126-
isProcessing = false;
127-
}
128-
}
129-
```
175+
**Word-level (on `<span>` wrapping a partially changed word):**
176+
`inserted-word`, `deleted-word`, `modified-word`
130177

131-
## 🔧 Component Parameters
178+
**Character-level (on `<span>` wrapping specific changed characters):**
179+
`inserted-character`, `deleted-character`, `modified-character`
132180

133-
| Parameter | Type | Default | Description |
134-
|-----------|------|---------|-------------|
135-
| `OldText` | `string` | `""` | The original text (left side) |
136-
| `NewText` | `string` | `""` | The modified text (right side) |
137-
| `CollapseContent` | `bool` | `false` | Collapse large diff sections |
138-
| `ShowWhiteSpace` | `bool` | `false` | Visualize spaces and tabs |
139-
| `IgnoreCase` | `bool` | `false` | Ignore case differences |
140-
| `IgnoreWhiteSpace` | `bool` | `false` | Ignore whitespace differences |
181+
**Stats badges:**
182+
`diff-stats-badge`, `primary`, `success`, `danger`, `warning`, `info`
141183

142-
## 🎨 Customization
184+
### All CSS Custom Properties
143185

144-
The component uses CSS classes that you can override:
186+
| Property | Default | Description |
187+
|---|---|---|
188+
| `--diff-bg-primary` | `#ffffff` | Main background |
189+
| `--diff-bg-secondary` | `#f6f8fa` | Header/footer background |
190+
| `--diff-bg-tertiary` | `#f1f3f4` | Hover background |
191+
| `--diff-border-primary` | `#e1e4e8` | Border color |
192+
| `--diff-text-primary` | `#24292e` | Main text color |
193+
| `--diff-text-muted` | `#656d76` | Line number color |
194+
| `--diff-text-accent` | `#0969da` | Accent/focus color |
195+
| `--diff-addition-bg` | `#e6ffed` | Added line & word background |
196+
| `--diff-addition-border` | `#2ea043` | Added line left border |
197+
| `--diff-addition-highlight` | `#7ce89b` | Added character highlight |
198+
| `--diff-deletion-bg` | `#ffeef0` | Deleted line & word background |
199+
| `--diff-deletion-border` | `#f85149` | Deleted line left border |
200+
| `--diff-deletion-highlight` | `#f9a8b0` | Deleted character highlight |
201+
| `--diff-modification-bg` | `#fff8c5` | Modified line & word background |
202+
| `--diff-modification-border` | `#fb8500` | Modified line left border |
203+
| `--diff-modification-highlight` | `#ffc833` | Modified character highlight |
204+
| `--diff-char-radius` | `3px` | Character highlight border-radius |
205+
| `--diff-char-padding` | `1px 2px` | Character highlight padding |
206+
| `--diff-word-radius` | `3px` | Word highlight border-radius |
207+
| `--diff-word-padding` | `1px 0` | Word highlight padding |
208+
| `--diff-shadow` | `0 1px 3px ...` | Container shadow |
209+
| `--diff-shadow-hover` | `0 2px 6px ...` | Container shadow on hover |
145210

146-
```css
147-
.diff-container { /* Main container */ }
148-
.diff-line-added { /* Added lines */ }
149-
.diff-line-deleted { /* Deleted lines */ }
150-
.diff-line-modified { /* Modified lines */ }
151-
.diff-line-unchanged { /* Unchanged lines */ }
152-
```
211+
Dark mode overrides are built in via `@media (prefers-color-scheme: dark)`.
212+
213+
## AI-Assisted Development
153214

154-
## 📄 License
215+
This project uses AI as a development tool to help improve and maintain the library. AI assists with tasks such as code refactoring, writing tests, updating documentation, and implementing new features. All changes are generally reviewed by a human before being merged, but due to limited contributor availability and a lack of pull requests, AI is used to keep the project moving forward and ensure it stays up to date.
155216

156-
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
217+
If you spot anything that looks off or have suggestions, contributions and issues are always welcome.
157218

158-
## 🙏 Acknowledgments
219+
## License
159220

160-
- [DiffPlex](https://github.com/mmanela/diffplex) - The core diffing library
161-
- [Blazor](https://blazor.net/) - The web framework that makes this possible
221+
MIT — see [LICENSE](LICENSE).
162222

163-
---
223+
## Acknowledgments
164224

165-
<div align="center">
166-
Made with ❤️ for the Blazor community
167-
</div>
225+
- [DiffPlex](https://github.com/mmanela/diffplex) — core diffing engine
226+
- [Blazor](https://blazor.net/) — web framework

0 commit comments

Comments
 (0)