All files / ngui-list/src ngui-list-item.directive.ts

97.82% Statements 45/46
82.6% Branches 19/23
100% Functions 7/7
97.72% Lines 43/44

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 1041x                       1x 1x 1x 1x 1x           1x               7x 7x 7x 7x 7x 7x       2x 2x 2x 1x   1x 1x 1x           3x 3x 3x   3x 3x 3x 3x   3x   1x 1x   1x 1x   1x           2x   1x 1x   1x 1x             1x       1x 1x         1x 1x        
import {
  Directive,
  ElementRef,
  Host,
  HostListener,
  Input,
  OnInit,
  Optional,
  Renderer2,
  ViewContainerRef
} from '@angular/core';
 
import { NguiListDirective } from './ngui-list.directive';
import { NguiVirtualListComponent } from './ngui-virtual-list.component';
import { NguiAutocompleteComponent } from './ngui-autocomplete.component';
import { NoneSelect } from './none-select';
import { NoMatchFound } from './no-match-found';
 
// tabindex, keydown, keyup(ENTER, ESC), click
@Directive({
  selector: 'ngui-list-item' // eslint-disable-line
})
export class NguiListItemDirective implements OnInit {
  @Input('item') object: any; // eslint-disable-line
 
  nextSibling: HTMLElement;
  prevSibling: HTMLElement;
  parentListComp: NguiListDirective | NguiVirtualListComponent | NguiAutocompleteComponent;
 
  constructor(
    private el: ElementRef,
    private renderer: Renderer2,
    private viewContainer: ViewContainerRef,
    @Optional() @Host() private listDirective: NguiListDirective,
    @Optional() @Host() private virtualListComponent: NguiVirtualListComponent,
    @Optional() @Host() private autocompleteComponent: NguiAutocompleteComponent
  ) { }
 
  ngOnInit(): void {
    this.renderer.setAttribute(this.el.nativeElement, 'tabindex', '0');
    this.parentListComp = this.listDirective || this.virtualListComponent || this.autocompleteComponent;
    if (!this.parentListComp) {
      throw Error('ngui-list-item requires parent of ngui-list, ngui-virtual-list, or ngui-autocomplete.');
    }
    if ((this.object instanceof NoneSelect) || (this.object instanceof NoMatchFound)) {
      this.viewContainer.clear();
      this.el.nativeElement.innerHTML = this.object.html;
    }
  }
 
  // handles keyboard up, down, left, right
  @HostListener('keydown', ['$event']) keydown(event): void {
    const thisListItem = this.el.nativeElement;
    const keyCode = event.which || event.keyCode;
    const parentListEl = this.parentListComp.element.nativeElement;
    const listItems: Array<HTMLElement>
      = Array.from(parentListEl.querySelectorAll('ngui-list-item'));
    const listItemNdx = listItems.indexOf(thisListItem);
    const nextListItem = listItems[listItemNdx + 1] || listItems[0];
    const prevListItem = listItems[listItemNdx - 1] || listItems[listItems.length - 1];
 
    switch (keyCode) {
    case 37: case 38: // up arrow, left arrow
      prevListItem.focus();
      break;
    case 39: case 40: // down arrow, right arrow
      nextListItem.focus();
      break;
    default:
      break;
    }
  }
 
  // handles keyboard enter(13), esc(27)
  @HostListener('keyup', ['$event']) keyup(event): void {
    switch (event.key) {
    case 'Enter':
      this.parentListComp.selected.emit(this.object);
      break;
    case 'Escape':
      this.parentListComp.escaped.emit();
      break;
    default:
      break;
    }
  }
 
  @HostListener('click', ['$event']) mousedown(): void {
    this.parentListComp.selected.emit(this.object);
  }
 
  @HostListener('focus', ['$event']) focused(): void {
    if (this.parentListComp['setFocused']) {
      this.parentListComp['setFocused']('listItem', true);
    }
  }
 
  @HostListener('blur', ['$event']) blurred(): void {
    if (this.parentListComp['setFocused']) {
      this.parentListComp['setFocused']('listItem', false);
    }
  }
}