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%); }