From ca90d1c4228a097b0a2c33a76457ceb7d20bc97e Mon Sep 17 00:00:00 2001 From: Hlars Date: Tue, 6 May 2025 21:54:46 +0200 Subject: [PATCH] multi color comment support --- .../comment-box/comment-box.component.html | 8 ++++- .../comment-box/comment-box.component.scss | 4 ++- src/app/comment-box/comment-box.component.ts | 36 ++++++++++++++----- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/app/comment-box/comment-box.component.html b/src/app/comment-box/comment-box.component.html index 2db2f45..60d6755 100644 --- a/src/app/comment-box/comment-box.component.html +++ b/src/app/comment-box/comment-box.component.html @@ -29,10 +29,16 @@ ]" (overlayOutsideClick)="clickOutsideMenu($event)">
+ @if (filteredSelectionList.length > 0) { @for (item of filteredSelectionList; track item; let index_ = $index) {
{{item}} + [class.active]="index_ === selectedDropdownItemIndex" (click)="clickMention(index_)">{{item.title}} +
+ } + } @else { +
+ Keine Übereinstimmung...
}
diff --git a/src/app/comment-box/comment-box.component.scss b/src/app/comment-box/comment-box.component.scss index da1f591..76950b4 100644 --- a/src/app/comment-box/comment-box.component.scss +++ b/src/app/comment-box/comment-box.component.scss @@ -8,11 +8,13 @@ } .mention { + --mention-color: blue; + display: inline-block; position: relative; &:not(.ignore) { - color: blue; + color: var(--mention-color); background-color: transparent; font-style: italic; font-size: 0.8rem; diff --git a/src/app/comment-box/comment-box.component.ts b/src/app/comment-box/comment-box.component.ts index e2fe1a2..755dc72 100644 --- a/src/app/comment-box/comment-box.component.ts +++ b/src/app/comment-box/comment-box.component.ts @@ -9,6 +9,11 @@ import { OverlayModule } from '@angular/cdk/overlay'; import { DOWN_ARROW, ENTER, ESCAPE, TAB, UP_ARROW } from '@angular/cdk/keycodes'; import { Cursor, MentionHandleResult } from './cursor'; +export interface MentionItem { + title: string, + color?: string, +} + @Component({ selector: 'app-comment-box', imports: [MatMenuModule, OverlayModule], @@ -155,7 +160,7 @@ export class CommentBoxComponent implements MatFormFieldControl, Control @ViewChild('commentInput') _commentInputRef!: ElementRef; @ViewChild('menuContent') _menuContent!: ElementRef; - @Input() mentionListItems: string[] = []; + @Input() mentionListItems: MentionItem[] = []; selectedDropdownItemIndex = 0; menuOffsetX = 0; @@ -163,7 +168,7 @@ export class CommentBoxComponent implements MatFormFieldControl, Control menuOpenAboveYShift = 0; isOpen = false; - filteredSelectionList: string[] = []; + filteredSelectionList: MentionItem[] = []; handleKeyEvent(event: KeyboardEvent) { if (this.isOpen) { @@ -180,9 +185,16 @@ export class CommentBoxComponent implements MatFormFieldControl, Control this.removeFocusedMention(event.target as HTMLInputElement); event.preventDefault(); break; - case ENTER || TAB: - this.addMention(event.target as HTMLInputElement); - this.handleTextChanged(true, 1); + case ENTER: + case TAB: + if (this.filteredSelectionList[this.selectedDropdownItemIndex]) { + this.addMention(event.target as HTMLInputElement); + this.handleTextChanged(true, 1); + } else { + this.removeFocusedMention(event.target as HTMLInputElement); + this.isOpen = false; + } + event.preventDefault(); break; } @@ -230,7 +242,7 @@ export class CommentBoxComponent implements MatFormFieldControl, Control // filter menu entries let searchQuery = focusedMentionElement.textContent?.substring(1); - this.filteredSelectionList = this.mentionListItems.filter((element) => element.toLocaleLowerCase().includes(searchQuery?.toLocaleLowerCase() ?? "")) + this.filteredSelectionList = this.mentionListItems.filter((element) => element.title.toLocaleLowerCase().includes(searchQuery?.toLocaleLowerCase() ?? "")) if (this.selectedDropdownItemIndex > this.filteredSelectionList.length - 1) this.selectedDropdownItemIndex = this.filteredSelectionList.length - 1; @@ -245,11 +257,12 @@ export class CommentBoxComponent implements MatFormFieldControl, Control handleMentionElements(innerHtml: string): MentionHandleResult { let newOffset = null; - innerHtml = innerHtml.replace(/(?|\w))@\w*/g, (match) => { + // innerHtml = innerHtml.replace(/(?|\w))@\w*/g, (match) => { + innerHtml = innerHtml.replace(/(?|\w))@\w*/g, (match) => { newOffset = match.length; return `
${match}
`; }); - + console.log(innerHtml) // remove old focus classes if match was found if (newOffset) { innerHtml = innerHtml.replaceAll(/class="focused"/g, ""); @@ -303,14 +316,19 @@ export class CommentBoxComponent implements MatFormFieldControl, Control } addMention(element: HTMLElement) { + const mentionItem = this.filteredSelectionList[this.selectedDropdownItemIndex]; + let focusedMention = element.querySelector(`.mention.${Cursor.focusedClassName}`); let focusedElements = element.querySelectorAll(Cursor.focusedClassName); if (focusedMention) { // set text and remove ignore to style mention - focusedMention.textContent = `@${this.filteredSelectionList[this.selectedDropdownItemIndex]}`; + focusedMention.textContent = `@${mentionItem.title}`; focusedMention.classList.remove(Cursor.focusedClassName); focusedMention.classList.remove("ignore") + if (mentionItem.color) + focusedMention.setAttribute('style', `--mention-color:${mentionItem.color}`) + // remove all old focused classes for (let node of focusedElements) { node.classList.remove(Cursor.focusedClassName);