multi color comment support
This commit is contained in:
parent
2190cc06e4
commit
ca90d1c422
@ -29,10 +29,16 @@
|
|||||||
]" (overlayOutsideClick)="clickOutsideMenu($event)">
|
]" (overlayOutsideClick)="clickOutsideMenu($event)">
|
||||||
<div class="mat-mdc-menu-panel" #menuContent>
|
<div class="mat-mdc-menu-panel" #menuContent>
|
||||||
<div class="mat-mdc-menu-content">
|
<div class="mat-mdc-menu-content">
|
||||||
|
@if (filteredSelectionList.length > 0) {
|
||||||
@for (item of filteredSelectionList; track item; let index_ = $index) {
|
@for (item of filteredSelectionList; track item; let index_ = $index) {
|
||||||
<div class="mat-mdc-menu-item mat-focus-indicator"
|
<div class="mat-mdc-menu-item mat-focus-indicator"
|
||||||
[class.mat-mdc-menu-item-highlighted]="index_ === selectedDropdownItemIndex"
|
[class.mat-mdc-menu-item-highlighted]="index_ === selectedDropdownItemIndex"
|
||||||
[class.active]="index_ === selectedDropdownItemIndex" (click)="clickMention(index_)">{{item}}
|
[class.active]="index_ === selectedDropdownItemIndex" (click)="clickMention(index_)">{{item.title}}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
} @else {
|
||||||
|
<div class="mat-mdc-menu-item mat-focus-indicator">
|
||||||
|
Keine Übereinstimmung...
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,11 +8,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mention {
|
.mention {
|
||||||
|
--mention-color: blue;
|
||||||
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&:not(.ignore) {
|
&:not(.ignore) {
|
||||||
color: blue;
|
color: var(--mention-color);
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
|
@ -9,6 +9,11 @@ import { OverlayModule } from '@angular/cdk/overlay';
|
|||||||
import { DOWN_ARROW, ENTER, ESCAPE, TAB, UP_ARROW } from '@angular/cdk/keycodes';
|
import { DOWN_ARROW, ENTER, ESCAPE, TAB, UP_ARROW } from '@angular/cdk/keycodes';
|
||||||
import { Cursor, MentionHandleResult } from './cursor';
|
import { Cursor, MentionHandleResult } from './cursor';
|
||||||
|
|
||||||
|
export interface MentionItem {
|
||||||
|
title: string,
|
||||||
|
color?: string,
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-comment-box',
|
selector: 'app-comment-box',
|
||||||
imports: [MatMenuModule, OverlayModule],
|
imports: [MatMenuModule, OverlayModule],
|
||||||
@ -155,7 +160,7 @@ export class CommentBoxComponent implements MatFormFieldControl<string>, Control
|
|||||||
@ViewChild('commentInput') _commentInputRef!: ElementRef;
|
@ViewChild('commentInput') _commentInputRef!: ElementRef;
|
||||||
@ViewChild('menuContent') _menuContent!: ElementRef;
|
@ViewChild('menuContent') _menuContent!: ElementRef;
|
||||||
|
|
||||||
@Input() mentionListItems: string[] = [];
|
@Input() mentionListItems: MentionItem[] = [];
|
||||||
|
|
||||||
selectedDropdownItemIndex = 0;
|
selectedDropdownItemIndex = 0;
|
||||||
menuOffsetX = 0;
|
menuOffsetX = 0;
|
||||||
@ -163,7 +168,7 @@ export class CommentBoxComponent implements MatFormFieldControl<string>, Control
|
|||||||
menuOpenAboveYShift = 0;
|
menuOpenAboveYShift = 0;
|
||||||
|
|
||||||
isOpen = false;
|
isOpen = false;
|
||||||
filteredSelectionList: string[] = [];
|
filteredSelectionList: MentionItem[] = [];
|
||||||
|
|
||||||
handleKeyEvent(event: KeyboardEvent) {
|
handleKeyEvent(event: KeyboardEvent) {
|
||||||
if (this.isOpen) {
|
if (this.isOpen) {
|
||||||
@ -180,9 +185,16 @@ export class CommentBoxComponent implements MatFormFieldControl<string>, Control
|
|||||||
this.removeFocusedMention(event.target as HTMLInputElement);
|
this.removeFocusedMention(event.target as HTMLInputElement);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
break;
|
break;
|
||||||
case ENTER || TAB:
|
case ENTER:
|
||||||
this.addMention(event.target as HTMLInputElement);
|
case TAB:
|
||||||
this.handleTextChanged(true, 1);
|
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();
|
event.preventDefault();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -230,7 +242,7 @@ export class CommentBoxComponent implements MatFormFieldControl<string>, Control
|
|||||||
|
|
||||||
// filter menu entries
|
// filter menu entries
|
||||||
let searchQuery = focusedMentionElement.textContent?.substring(1);
|
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)
|
if (this.selectedDropdownItemIndex > this.filteredSelectionList.length - 1)
|
||||||
this.selectedDropdownItemIndex = this.filteredSelectionList.length - 1;
|
this.selectedDropdownItemIndex = this.filteredSelectionList.length - 1;
|
||||||
|
|
||||||
@ -245,11 +257,12 @@ export class CommentBoxComponent implements MatFormFieldControl<string>, Control
|
|||||||
|
|
||||||
handleMentionElements(innerHtml: string): MentionHandleResult {
|
handleMentionElements(innerHtml: string): MentionHandleResult {
|
||||||
let newOffset = null;
|
let newOffset = null;
|
||||||
innerHtml = innerHtml.replace(/(?<!(<div class[ \t]*=[ \t]*"[^"]*mention[^"]*">|\w))@\w*/g, (match) => {
|
// innerHtml = innerHtml.replace(/(?<!(<div class[ \t]*=[ \t]*"[^"]*mention[^"]*">|\w))@\w*/g, (match) => {
|
||||||
|
innerHtml = innerHtml.replace(/(?<!(<div class[ \t]*=[ \t]*"[^"]*mention[^"]*"[ \t]*(style[ \t]*=[ \t]*".*[ \t]*")?>|\w))@\w*/g, (match) => {
|
||||||
newOffset = match.length;
|
newOffset = match.length;
|
||||||
return `<div class="${Cursor.focusedClassName} ignore mention">${match}</div>`;
|
return `<div class="${Cursor.focusedClassName} ignore mention">${match}</div>`;
|
||||||
});
|
});
|
||||||
|
console.log(innerHtml)
|
||||||
// remove old focus classes if match was found
|
// remove old focus classes if match was found
|
||||||
if (newOffset) {
|
if (newOffset) {
|
||||||
innerHtml = innerHtml.replaceAll(/class="focused"/g, "");
|
innerHtml = innerHtml.replaceAll(/class="focused"/g, "");
|
||||||
@ -303,14 +316,19 @@ export class CommentBoxComponent implements MatFormFieldControl<string>, Control
|
|||||||
}
|
}
|
||||||
|
|
||||||
addMention(element: HTMLElement) {
|
addMention(element: HTMLElement) {
|
||||||
|
const mentionItem = this.filteredSelectionList[this.selectedDropdownItemIndex];
|
||||||
|
|
||||||
let focusedMention = element.querySelector(`.mention.${Cursor.focusedClassName}`);
|
let focusedMention = element.querySelector(`.mention.${Cursor.focusedClassName}`);
|
||||||
let focusedElements = element.querySelectorAll(Cursor.focusedClassName);
|
let focusedElements = element.querySelectorAll(Cursor.focusedClassName);
|
||||||
if (focusedMention) {
|
if (focusedMention) {
|
||||||
// set text and remove ignore to style mention
|
// 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(Cursor.focusedClassName);
|
||||||
focusedMention.classList.remove("ignore")
|
focusedMention.classList.remove("ignore")
|
||||||
|
|
||||||
|
if (mentionItem.color)
|
||||||
|
focusedMention.setAttribute('style', `--mention-color:${mentionItem.color}`)
|
||||||
|
|
||||||
// remove all old focused classes
|
// remove all old focused classes
|
||||||
for (let node of focusedElements) {
|
for (let node of focusedElements) {
|
||||||
node.classList.remove(Cursor.focusedClassName);
|
node.classList.remove(Cursor.focusedClassName);
|
||||||
|
Loading…
Reference in New Issue
Block a user