Loading src/mention/mention-list.component.ts +37 −3 Original line number Diff line number Diff line import { Component, ElementRef, Output, EventEmitter } from '@angular/core'; import {Component, ElementRef, Output, EventEmitter, ViewChild} from '@angular/core'; import { isInputOrTextAreaElement, getContentEditableCaretCoords } from './mention-utils'; import { getCaretCoordinates } from './caret-coords'; Loading @@ -24,7 +24,7 @@ import { getCaretCoordinates } from './caret-coords'; } `], template: ` <ul class="dropdown-menu scrollable-menu" [hidden]="hidden"> <ul class="dropdown-menu scrollable-menu" #list [hidden]="hidden"> <li *ngFor="let item of items; let i = index" [class.active]="activeIndex==i"> <a class="text-primary" (mousedown)="activeIndex=i;itemClick.emit();$event.preventDefault()">{{item}}</a> </li> Loading @@ -35,6 +35,7 @@ export class MentionListComponent { items = []; activeIndex: number = 0; hidden: boolean = false; @ViewChild('list') list : ElementRef; @Output() itemClick = new EventEmitter(); constructor(private _element: ElementRef) {} Loading Loading @@ -74,13 +75,46 @@ export class MentionListComponent { el.style.left = coords.left + 'px'; el.style.top = coords.top + 'px'; } get activeItem() { return this.items[this.activeIndex]; } activateNextItem() { // adjust scrollable-menu offset if the next item is out of view let listEl: HTMLElement = this.list.nativeElement; let activeEl = listEl.getElementsByClassName('active').item(0); if (activeEl) { let nextLiEl: HTMLElement = <HTMLElement> activeEl.nextSibling; if (nextLiEl && nextLiEl.nodeName == "LI") { let nextLiRect: ClientRect = nextLiEl.getBoundingClientRect(); if (nextLiRect.bottom > listEl.getBoundingClientRect().bottom) { listEl.scrollTop = nextLiEl.offsetTop + nextLiRect.height - listEl.clientHeight; } } } // select the next item this.activeIndex = Math.max(Math.min(this.activeIndex + 1, this.items.length - 1), 0); } activatePreviousItem() { // adjust the scrollable-menu offset if the previous item is out of view let listEl: HTMLElement = this.list.nativeElement; let activeEl = listEl.getElementsByClassName('active').item(0); if (activeEl) { let prevLiEl: HTMLElement = <HTMLElement> activeEl.previousSibling; if (prevLiEl && prevLiEl.nodeName == "LI") { let prevLiRect: ClientRect = prevLiEl.getBoundingClientRect(); if (prevLiRect.top < listEl.getBoundingClientRect().top) { listEl.scrollTop = prevLiEl.offsetTop; } } } // select the previous item this.activeIndex = Math.max(Math.min(this.activeIndex - 1, this.items.length - 1), 0); } resetScroll() { this.list.nativeElement.scrollTop = 0; } } src/mention/mention.directive.ts +2 −1 Original line number Diff line number Diff line Loading @@ -183,6 +183,7 @@ export class MentionDirective { this.searchList.items = this.items; this.searchList.hidden = false; this.searchList.position(nativeElement, this.iframe); window.setTimeout(() => this.searchList.resetScroll()); } } } Loading
src/mention/mention-list.component.ts +37 −3 Original line number Diff line number Diff line import { Component, ElementRef, Output, EventEmitter } from '@angular/core'; import {Component, ElementRef, Output, EventEmitter, ViewChild} from '@angular/core'; import { isInputOrTextAreaElement, getContentEditableCaretCoords } from './mention-utils'; import { getCaretCoordinates } from './caret-coords'; Loading @@ -24,7 +24,7 @@ import { getCaretCoordinates } from './caret-coords'; } `], template: ` <ul class="dropdown-menu scrollable-menu" [hidden]="hidden"> <ul class="dropdown-menu scrollable-menu" #list [hidden]="hidden"> <li *ngFor="let item of items; let i = index" [class.active]="activeIndex==i"> <a class="text-primary" (mousedown)="activeIndex=i;itemClick.emit();$event.preventDefault()">{{item}}</a> </li> Loading @@ -35,6 +35,7 @@ export class MentionListComponent { items = []; activeIndex: number = 0; hidden: boolean = false; @ViewChild('list') list : ElementRef; @Output() itemClick = new EventEmitter(); constructor(private _element: ElementRef) {} Loading Loading @@ -74,13 +75,46 @@ export class MentionListComponent { el.style.left = coords.left + 'px'; el.style.top = coords.top + 'px'; } get activeItem() { return this.items[this.activeIndex]; } activateNextItem() { // adjust scrollable-menu offset if the next item is out of view let listEl: HTMLElement = this.list.nativeElement; let activeEl = listEl.getElementsByClassName('active').item(0); if (activeEl) { let nextLiEl: HTMLElement = <HTMLElement> activeEl.nextSibling; if (nextLiEl && nextLiEl.nodeName == "LI") { let nextLiRect: ClientRect = nextLiEl.getBoundingClientRect(); if (nextLiRect.bottom > listEl.getBoundingClientRect().bottom) { listEl.scrollTop = nextLiEl.offsetTop + nextLiRect.height - listEl.clientHeight; } } } // select the next item this.activeIndex = Math.max(Math.min(this.activeIndex + 1, this.items.length - 1), 0); } activatePreviousItem() { // adjust the scrollable-menu offset if the previous item is out of view let listEl: HTMLElement = this.list.nativeElement; let activeEl = listEl.getElementsByClassName('active').item(0); if (activeEl) { let prevLiEl: HTMLElement = <HTMLElement> activeEl.previousSibling; if (prevLiEl && prevLiEl.nodeName == "LI") { let prevLiRect: ClientRect = prevLiEl.getBoundingClientRect(); if (prevLiRect.top < listEl.getBoundingClientRect().top) { listEl.scrollTop = prevLiEl.offsetTop; } } } // select the previous item this.activeIndex = Math.max(Math.min(this.activeIndex - 1, this.items.length - 1), 0); } resetScroll() { this.list.nativeElement.scrollTop = 0; } }
src/mention/mention.directive.ts +2 −1 Original line number Diff line number Diff line Loading @@ -183,6 +183,7 @@ export class MentionDirective { this.searchList.items = this.items; this.searchList.hidden = false; this.searchList.position(nativeElement, this.iframe); window.setTimeout(() => this.searchList.resetScroll()); } } }