{"id":23888352,"url":"https://github.com/lzinga/blazortextdiff","last_synced_at":"2026-02-23T20:26:11.855Z","repository":{"id":52967419,"uuid":"237501574","full_name":"lzinga/BlazorTextDiff","owner":"lzinga","description":"A blazor component to display side by side text diff.","archived":false,"fork":false,"pushed_at":"2022-10-28T17:19:03.000Z","size":236,"stargazers_count":30,"open_issues_count":5,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-24T06:04:44.015Z","etag":null,"topics":["blazor","blazor-component","component","diff","text-diff"],"latest_commit_sha":null,"homepage":"https://www.nuget.org/packages/BlazorTextDiff","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lzinga.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-31T19:29:36.000Z","updated_at":"2024-12-09T09:25:15.000Z","dependencies_parsed_at":"2023-01-20T12:47:14.789Z","dependency_job_id":null,"html_url":"https://github.com/lzinga/BlazorTextDiff","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lzinga%2FBlazorTextDiff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lzinga%2FBlazorTextDiff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lzinga%2FBlazorTextDiff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lzinga%2FBlazorTextDiff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lzinga","download_url":"https://codeload.github.com/lzinga/BlazorTextDiff/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248161261,"owners_count":21057553,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blazor","blazor-component","component","diff","text-diff"],"created_at":"2025-01-04T08:47:03.429Z","updated_at":"2026-02-23T20:26:11.847Z","avatar_url":"https://github.com/lzinga.png","language":"HTML","readme":"# BlazorTextDiff\n\nA Blazor component for displaying side-by-side text differences with character-level highlighting. Built on [DiffPlex](https://github.com/mmanela/diffplex).\n\n## Features\n\n- Side-by-side diff with line numbers\n- Character-level highlighting within changed lines\n- Word-level soft highlight with character-level strong highlight for partial changes\n- Adjacent character highlights merge into smooth pill shapes\n- Collapse/expand unchanged sections\n- Ignore case and whitespace options\n- Custom header with diff statistics\n- Custom CSS class and attribute support\n- Fully themeable via CSS custom properties\n- Dark mode via `prefers-color-scheme`\n- Responsive and accessible\n\n## Status\n\n[![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)\n[![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)\n[![NuGet](https://img.shields.io/nuget/v/BlazorTextDiff.svg)](https://www.nuget.org/packages/BlazorTextDiff/)\n\n## Live Demo\n\n[https://lzinga.github.io/BlazorTextDiff/](https://lzinga.github.io/BlazorTextDiff/)\n\n## Installation\n\n```bash\ndotnet add package BlazorTextDiff\n```\n\n## Setup\n\nAdd the stylesheet to your `index.html` or `_Host.cshtml`:\n\n```html\n\u003clink href=\"_content/BlazorTextDiff/css/BlazorDiff.css\" rel=\"stylesheet\" /\u003e\n```\n\nNo JavaScript or service registration is required.\n\n## Usage\n\n### Basic\n\n```razor\n\u003cTextDiff OldText=\"@oldText\" NewText=\"@newText\" /\u003e\n```\n\n### With Options\n\n```razor\n\u003cTextDiff OldText=\"@oldText\"\n          NewText=\"@newText\"\n          CollapseContent=\"true\"\n          IgnoreCase=\"true\"\n          IgnoreWhiteSpace=\"false\"\n          Class=\"my-diff\"\u003e\n    \u003cHeader\u003e\n        \u003cdiv style=\"padding: 10px 12px;\"\u003e\n            \u003cspan class=\"diff-stats-badge warning\"\u003e@context.LineModificationCount modified\u003c/span\u003e\n            \u003cspan class=\"diff-stats-badge danger\"\u003e@context.LineDeletionCount deleted\u003c/span\u003e\n            \u003cspan class=\"diff-stats-badge success\"\u003e@context.LineAdditionCount added\u003c/span\u003e\n        \u003c/div\u003e\n    \u003c/Header\u003e\n\u003c/TextDiff\u003e\n```\n\n## Parameters\n\n| Parameter | Type | Default | Description |\n|---|---|---|---|\n| `OldText` | `string?` | `null` | Original text (left pane) |\n| `NewText` | `string?` | `null` | Modified text (right pane) |\n| `CollapseContent` | `bool` | `false` | Collapse unchanged sections |\n| `MaxHeight` | `int` | `300` | Max height (px) when collapsed |\n| `IgnoreCase` | `bool` | `false` | Ignore case differences |\n| `IgnoreWhiteSpace` | `bool` | `false` | Ignore whitespace differences |\n| `Header` | `RenderFragment\u003cDiffStats\u003e?` | `null` | Custom header template |\n| `Class` | `string?` | `null` | Additional CSS class(es) |\n\nUnmatched HTML attributes (`style`, `id`, `data-*`, etc.) are passed through to the root element.\n\n## How Character Highlighting Works\n\nThe component uses three levels of visual hierarchy:\n\n1. **Line-level** — the entire row gets a colored background (`inserted-line`, `deleted-line`, `modified-line`)\n2. **Word-level** — when a word is partially changed, it gets a soft background highlight (`inserted-word`, `deleted-word`, `modified-word`)\n3. **Character-level** — the specific changed characters get a strong highlight (`inserted-character`, `deleted-character`, `modified-character`)\n\nFor example, `Programing` → `Programming`:\n- The whole word wraps in `\u003cspan class=\"inserted-word\"\u003e` (soft green background)\n- Only the added `m` wraps in `\u003cspan class=\"inserted-character\"\u003e` (strong green highlight)\n\nWhen a word is entirely changed (e.g. `cat` → `dog`), it skips the word wrapper and uses the character-level class directly.\n\nAdjacent character highlights automatically merge into a single pill shape — rounded corners only appear on the first and last character in a run.\n\n## Customization\n\nAll visual styling is controlled via CSS custom properties. Override them in your own stylesheet to retheme the component.\n\n### Diff Colors\n\n```css\n:root {\n  /* Line-level backgrounds */\n  --diff-addition-bg: #e6ffed;\n  --diff-deletion-bg: #ffeef0;\n  --diff-modification-bg: #fff8c5;\n\n  /* Line-level left border accents */\n  --diff-addition-border: #2ea043;\n  --diff-deletion-border: #f85149;\n  --diff-modification-border: #fb8500;\n\n  /* Character-level strong highlights */\n  --diff-addition-highlight: #7ce89b;\n  --diff-deletion-highlight: #f9a8b0;\n  --diff-modification-highlight: #ffc833;\n}\n```\n\nThe word-level soft background reuses `--diff-*-bg` (same as the line), and the character-level strong highlight uses `--diff-*-highlight`.\n\n### Highlight Shape\n\n```css\n:root {\n  /* Character highlight pill shape */\n  --diff-char-radius: 3px;       /* border-radius for each character span */\n  --diff-char-padding: 1px 2px;  /* padding inside each character span */\n\n  /* Word highlight shape */\n  --diff-word-radius: 3px;       /* border-radius for the word wrapper */\n  --diff-word-padding: 1px 0;    /* padding inside the word wrapper */\n}\n```\n\nExamples:\n\n```css\n/* Sharp rectangles instead of rounded pills */\n:root { --diff-char-radius: 0; --diff-word-radius: 0; }\n\n/* Larger, more prominent pills */\n:root { --diff-char-radius: 6px; --diff-char-padding: 2px 4px; }\n\n/* Underline style (no background, border-bottom instead) */\n.my-diff .inserted-character { background: none; border-bottom: 2px solid #2ea043; }\n.my-diff .deleted-character  { background: none; border-bottom: 2px solid #f85149; text-decoration: line-through; }\n```\n\n### Scoped Overrides\n\nUse the `Class` parameter to scope styles to a specific instance:\n\n```css\n.my-diff .modified-line { background-color: #ffe0b2; }\n.my-diff .deleted-character { background-color: #e53935; color: #fff; }\n```\n\n### CSS Classes Reference\n\n**Layout:**\n`diff-container`, `diff-pane-left`, `diff-pane-right`, `diff-header`, `diff-panes`, `diff-expand-notice`\n\n**Line-level (on `\u003ctd\u003e`):**\n`inserted-line`, `deleted-line`, `modified-line`, `unchanged-line`\n\n**Word-level (on `\u003cspan\u003e` wrapping a partially changed word):**\n`inserted-word`, `deleted-word`, `modified-word`\n\n**Character-level (on `\u003cspan\u003e` wrapping specific changed characters):**\n`inserted-character`, `deleted-character`, `modified-character`\n\n**Stats badges:**\n`diff-stats-badge`, `primary`, `success`, `danger`, `warning`, `info`\n\n### All CSS Custom Properties\n\n| Property | Default | Description |\n|---|---|---|\n| `--diff-bg-primary` | `#ffffff` | Main background |\n| `--diff-bg-secondary` | `#f6f8fa` | Header/footer background |\n| `--diff-bg-tertiary` | `#f1f3f4` | Hover background |\n| `--diff-border-primary` | `#e1e4e8` | Border color |\n| `--diff-text-primary` | `#24292e` | Main text color |\n| `--diff-text-muted` | `#656d76` | Line number color |\n| `--diff-text-accent` | `#0969da` | Accent/focus color |\n| `--diff-addition-bg` | `#e6ffed` | Added line \u0026 word background |\n| `--diff-addition-border` | `#2ea043` | Added line left border |\n| `--diff-addition-highlight` | `#7ce89b` | Added character highlight |\n| `--diff-deletion-bg` | `#ffeef0` | Deleted line \u0026 word background |\n| `--diff-deletion-border` | `#f85149` | Deleted line left border |\n| `--diff-deletion-highlight` | `#f9a8b0` | Deleted character highlight |\n| `--diff-modification-bg` | `#fff8c5` | Modified line \u0026 word background |\n| `--diff-modification-border` | `#fb8500` | Modified line left border |\n| `--diff-modification-highlight` | `#ffc833` | Modified character highlight |\n| `--diff-char-radius` | `3px` | Character highlight border-radius |\n| `--diff-char-padding` | `1px 2px` | Character highlight padding |\n| `--diff-word-radius` | `3px` | Word highlight border-radius |\n| `--diff-word-padding` | `1px 0` | Word highlight padding |\n| `--diff-shadow` | `0 1px 3px ...` | Container shadow |\n| `--diff-shadow-hover` | `0 2px 6px ...` | Container shadow on hover |\n\nDark mode overrides are built in via `@media (prefers-color-scheme: dark)`.\n\n## AI-Assisted Development\n\nThis 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.\n\nIf you spot anything that looks off or have suggestions, contributions and issues are always welcome.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n## Acknowledgments\n\n- [DiffPlex](https://github.com/mmanela/diffplex) — core diffing engine\n- [Blazor](https://blazor.net/) — web framework\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flzinga%2Fblazortextdiff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flzinga%2Fblazortextdiff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flzinga%2Fblazortextdiff/lists"}