From 63183b37d169390b69600b59ad29d72898c97a85 Mon Sep 17 00:00:00 2001
From: Richard Russell <2265225+rars@users.noreply.github.com>
Date: Wed, 13 Mar 2024 12:20:26 +0000
Subject: [PATCH] feat(ngx-diff): add title bar to inline-diff
---
README.md | 13 ++--
.../inline-diff/inline-diff.component.html | 9 +++
.../inline-diff/inline-diff.component.scss | 67 ++++++++++++++++---
.../inline-diff/inline-diff.component.ts | 41 ++++++++----
src/app/app.component.html | 20 +++++-
src/styles.scss | 5 +-
6 files changed, 129 insertions(+), 26 deletions(-)
diff --git a/README.md b/README.md
index a91fa63..cd7476f 100644
--- a/README.md
+++ b/README.md
@@ -65,17 +65,22 @@ For version 3+, you can customise the appearance of the diff through various CSS
--ngx-diff-font-size: 1rem;
--ngx-diff-font-family: Consolas, Courier, monospace;
--ngx-diff-font-color: #000000;
+ --ngx-diff-title-bar-padding: 0.5rem;
+ --ngx-diff-title-font-weight: 600;
--ngx-diff-line-number-font-color: #484848;
--ngx-diff-line-number-hover-font-color: #ffffff;
--ngx-diff-selected-border-color: #ff8000;
- --ngx-diff-inserted-background-color: #9dff97;
- --ngx-diff-deleted-background-color: #ff8c8c;
- --ngx-diff-equal-background-color: #ffffff;
- --ngx-diff-margin-background-color: #dedede;
--ngx-diff-line-number-width: 2rem;
--ngx-diff-border-width: 1px;
--ngx-diff-line-left-padding: 1rem;
--ngx-diff-bottom-spacer-height: 1rem;
+
+ --ngx-diff-insert-color: #d6ffd6;
+ --ngx-diff-delete-color: #ffd6d6;
+ --ngx-diff-equal-color: #ffffff;
+ --ngx-diff-mix-color: #000;
+ --ngx-diff-light-mix-percentage: 2%;
+ --ngx-diff-heavy-mix-percentage: 10%;
}
```
diff --git a/projects/ngx-diff/src/lib/components/inline-diff/inline-diff.component.html b/projects/ngx-diff/src/lib/components/inline-diff/inline-diff.component.html
index 8cf8610..b741969 100644
--- a/projects/ngx-diff/src/lib/components/inline-diff/inline-diff.component.html
+++ b/projects/ngx-diff/src/lib/components/inline-diff/inline-diff.component.html
@@ -1,3 +1,12 @@
+
+ @if (title) {
+ {{ title }}
+ }
+ +++ {{ diffSummary.numLinesAdded }}
+ --- {{ diffSummary.numLinesRemoved }}
+
@if (isContentEqual) {
There are no changes to display.
}
diff --git a/projects/ngx-diff/src/lib/components/inline-diff/inline-diff.component.scss b/projects/ngx-diff/src/lib/components/inline-diff/inline-diff.component.scss
index e00a637..3b88724 100644
--- a/projects/ngx-diff/src/lib/components/inline-diff/inline-diff.component.scss
+++ b/projects/ngx-diff/src/lib/components/inline-diff/inline-diff.component.scss
@@ -1,19 +1,61 @@
:host {
--ngx-diff-border-color: #888888;
- --ngx-diff-font-size: 1rem;
+ --ngx-diff-font-size: 0.9rem;
--ngx-diff-font-family: Consolas, Courier, monospace;
--ngx-diff-font-color: #000000;
--ngx-diff-line-number-font-color: #484848;
--ngx-diff-line-number-hover-font-color: #ffffff;
--ngx-diff-selected-border-color: #ff8000;
- --ngx-diff-inserted-background-color: #9dff97;
- --ngx-diff-deleted-background-color: #ff8c8c;
- --ngx-diff-equal-background-color: #ffffff;
- --ngx-diff-margin-background-color: #dedede;
+
--ngx-diff-line-number-width: 2rem;
--ngx-diff-border-width: 1px;
--ngx-diff-line-left-padding: 1rem;
--ngx-diff-bottom-spacer-height: 1rem;
+ --ngx-diff-title-bar-padding: 0.5rem;
+ --ngx-diff-title-font-weight: 600;
+
+ --ngx-diff-insert-color: #d6ffd6;
+ --ngx-diff-delete-color: #ffd6d6;
+ --ngx-diff-equal-color: #ffffff;
+ --ngx-diff-mix-color: #000;
+ --ngx-diff-light-mix-percentage: 2%;
+ --ngx-diff-heavy-mix-percentage: 10%;
+
+ --ngx-diff-inserted-background-color: var(--ngx-diff-insert-color);
+ --ngx-diff-deleted-background-color: var(--ngx-diff-delete-color);
+ --ngx-diff-equal-background-color: var(--ngx-diff-equal-color);
+ --ngx-diff-margin-background-color: color-mix(in srgb, var(--ngx-diff-equal-color), var(--ngx-diff-mix-color) var(--ngx-diff-light-mix-percentage));
+
+ --ngx-diff-insert-color-darker: color-mix(in srgb, var(--ngx-diff-insert-color), var(--ngx-diff-mix-color) var(--ngx-diff-light-mix-percentage));
+ --ngx-diff-insert-color-darkest: color-mix(in srgb, var(--ngx-diff-insert-color), var(--ngx-diff-mix-color) var(--ngx-diff-heavy-mix-percentage));
+
+ --ngx-diff-delete-color-darker: color-mix(in srgb, var(--ngx-diff-delete-color), var(--ngx-diff-mix-color) var(--ngx-diff-light-mix-percentage));
+ --ngx-diff-delete-color-darkest: color-mix(in srgb, var(--ngx-diff-delete-color), var(--ngx-diff-mix-color) var(--ngx-diff-heavy-mix-percentage));
+}
+
+div.inline-diff-title-bar {
+ background-color: var(--ngx-diff-margin-background-color);
+ font-family: var(--ngx-diff-font-family);
+ font-size: var(--ngx-diff-font-size);
+ font-weight: var(--ngx-diff-title-font-weight);
+ padding: var(--ngx-diff-title-bar-padding);
+}
+
+div.inline-diff-no-changes-text {
+ font-family: var(--ngx-diff-font-family);
+ font-size: var(--ngx-diff-font-size);
+ font-weight: var(--ngx-diff-title-font-weight);
+ padding: var(--ngx-diff-title-bar-padding);
+ background-color: var(--ngx-diff-equal-background-color);
+ color: var(--ngx-diff-font-color);
+}
+
+.inline-diff-summary-lines-added {
+ color: var(--ngx-diff-insert-color-darkest);
+}
+
+.inline-diff-summary-lines-removed {
+ color: var(--ngx-diff-delete-color-darkest);
}
div.inline-diff {
@@ -28,7 +70,8 @@ div.inline-diff-content {
top: 0px;
left: 0px;
flex-grow: 1;
- overflow-x: scroll;
+ overflow-x: auto;
+ overflow-y: hidden;
}
div.inline-diff-content-wrapper {
@@ -70,11 +113,19 @@ div.inline-diff-text {
}
.inline-diff-delete {
- background-color: var(--ngx-diff-deleted-background-color);
+ background-color: var(--ngx-diff-delete-color-darker);
+
+ &.line-content {
+ background-color: var(--ngx-diff-deleted-background-color);
+ }
}
.inline-diff-insert {
- background-color: var(--ngx-diff-inserted-background-color);
+ background-color: var(--ngx-diff-insert-color-darker);
+
+ &.line-content {
+ background-color: var(--ngx-diff-inserted-background-color);
+ }
}
.inline-diff-delete > div {
diff --git a/projects/ngx-diff/src/lib/components/inline-diff/inline-diff.component.ts b/projects/ngx-diff/src/lib/components/inline-diff/inline-diff.component.ts
index 4765e2f..80f6997 100644
--- a/projects/ngx-diff/src/lib/components/inline-diff/inline-diff.component.ts
+++ b/projects/ngx-diff/src/lib/components/inline-diff/inline-diff.component.ts
@@ -27,26 +27,34 @@ type LineDiff = {
imports: [NgClass, LineNumberPipe],
})
export class InlineDiffComponent implements OnInit, OnChanges {
- @Input()
+ /**
+ * Optional title to be displayed at the top of the diff.
+ */
+ @Input({ required: false })
+ public title?: string;
+ @Input({ required: true })
public oldText: string | number | boolean | undefined;
- @Input()
+ @Input({ required: true })
public newText: string | number | boolean | undefined;
- // The number of lines of context to provide either side of a DiffOp.Insert or DiffOp.Delete diff.
- // Context is taken from a DiffOp.Equal section.
- @Input()
- public lineContextSize: number | undefined;
+ /**
+ * The number of lines of context to provide either side of a DiffOp.Insert or DiffOp.Delete diff.
+ * Context is taken from a DiffOp.Equal section.
+ */
+ @Input({ required: false })
+ public lineContextSize?: number;
@Output()
public selectedLineChange = new EventEmitter();
- public calculatedDiff: LineDiff[];
+ public diffSummary = {
+ numLinesAdded: 0,
+ numLinesRemoved: 0,
+ };
+ public calculatedDiff: LineDiff[] = [];
public selectedLine?: LineDiff;
- public isContentEqual: boolean;
+ public isContentEqual: boolean = false;
- public constructor(private readonly dmp: DiffMatchPatchService) {
- this.calculatedDiff = [];
- this.isContentEqual = false;
- }
+ public constructor(private readonly dmp: DiffMatchPatchService) {}
public ngOnInit(): void {
this.updateHtml();
@@ -169,6 +177,10 @@ export class InlineDiffComponent implements OnInit, OnChanges {
this.isContentEqual = diffs.length === 1 && diffs[0][0] === DiffOp.Equal;
if (this.isContentEqual) {
this.calculatedDiff = [];
+ this.diffSummary = {
+ numLinesAdded: 0,
+ numLinesRemoved: 0,
+ };
return;
}
@@ -212,6 +224,11 @@ export class InlineDiffComponent implements OnInit, OnChanges {
};
},
);
+
+ this.diffSummary = {
+ numLinesAdded: this.calculatedDiff.filter((x) => x.type === LineDiffType.Insert).length,
+ numLinesRemoved: this.calculatedDiff.filter((x) => x.type === LineDiffType.Delete).length,
+ };
}
/* If the number of diffLines is greater than lineContextSize then we may need to adjust the diff
diff --git a/src/app/app.component.html b/src/app/app.component.html
index b1d55cc..01d5326 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -7,10 +7,11 @@
style="width: 100%"
(selectedLineChange)="selectedLineChange($event)"
/>
-
+
+
+
+
+
diff --git a/src/styles.scss b/src/styles.scss
index 2ab2c9e..ae27217 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -10,7 +10,10 @@
--ngx-diff-line-left-padding: 1rem;
--ngx-diff-bottom-spacer-height: 1rem;
-
+ --ngx-diff-insert-color-darker: color-mix(in srgb, var(--ngx-diff-insert-color), #000 15%);
+ --ngx-diff-insert-color-darkest: color-mix(in srgb, var(--ngx-diff-insert-color), #000 30%);
+ --ngx-diff-delete-color-darker: color-mix(in srgb, var(--ngx-diff-delete-color), #000 15%);
+ --ngx-diff-delete-color-darkest: color-mix(in srgb, var(--ngx-diff-delete-color), #000 30%);
}