All files / lib/internal listbox-item.directive.ts

100% Statements 119/119
100% Branches 31/31
100% Functions 14/14
100% Lines 119/119

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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 1201x 1x 1x 1x 1x 1x 1x 1x 1x 1x 26x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1298x 1298x 1298x 26821x 26821x 26821x 26821x 28085x 28085x 28085x 28085x 28085x 28085x 28085x 28085x 28085x 28085x 26486x 1599x 1599x 28085x 28085x 28085x 28085x 28085x 28085x 28085x 28085x 28085x 28085x 28085x 1x 1x 1x 1x 1x 1x 1x 1x 1x 26x 17x 26x 26x 26x 1x 1x 1x 1x 26x 17x 1x 1x 1x 1x 1x 39x 1x 1x 1x 1298x 1298x 1298x 1298x 1298x 1x 1x 1x 28151x 26853x 1x 1x 1x 1x 1x 1x 84x 1x 1x 1x 61x 1x 1x 1x 67x 1x 1x 1x  
import { Directive, ElementRef, HostBinding, HostListener, Input } from '@angular/core';
import { IndexedItem } from '../utils/internal-utils';
import { Key } from '../utils/util.types';
import { ListBoxDirective } from './listbox.directive';
 
 
@Directive({
  selector: '[listbox-item]'
})
export class ListBoxItemDirective {
 
  @Input('listbox-item')
  public item!: IndexedItem<unknown>;
 
  @HostBinding('attr.id')
  public itemId?: string;
 
  @HostBinding('attr.role')
  public readonly role = 'option';
 
  // Does not work on JAWS
  //  @HostBinding('attr.aria-selected')
  //  get ariaSelected(): boolean {
  //    return this.selected;
  //  }
 
  @HostBinding('attr.area-posinset')
  public ariaPosInSet = 1;
 
  @HostBinding('attr.aria-setsize')
  public ariaSetSize = 1;
 
  get index(): number {
    return this.item.index;
  }
 
  get key(): Key {
    return this.item.key;
  }
 
  get selected(): boolean {
    return this._listbox?.isKeySelected(this.key);
  }
 
  @HostBinding('attr.tabindex')
  public get tabindex(): number | null {
    // a tabindex of -1 allows the node to get the native focus
    if (this._listbox?.focusMode == 'native') {
      return -1;
    } else {
      return null;
    }
  } 
 
  @HostBinding('class.gc-selected')
  get classSelected(): boolean {
    return this.selected;
  }
 
  @HostBinding('class.gc-focused')
  get classFocused(): boolean {
    return this.isFocused();
  }
 
  private _listbox!: ListBoxDirective;
 
  constructor(private el: ElementRef,
    /*Fails in storybook hence done in MenuDirective  private menu: MenuDirective<T>*/) {}
 
  @HostListener('click', [ '$event' ])
  _handleMenuItemClicked(event: MouseEvent): void {
    if (this._listbox.focusMode === 'virtual') {
      this.focus();
    }
    this._listbox.selectItem(this.item.item);
    event.preventDefault();
  }
  
  @HostListener('mousedown', [ '$event' ])
  _handleMenuItemMouseDown(event: MouseEvent): void {
    if (this._listbox.focusMode === 'virtual') {
      event.preventDefault();
    }
  }
 
  @HostListener('keydown', [ '$event' ])
  _handleMenuItemKeyDown(event: KeyboardEvent): void {
    this._listbox.handleKeyDown(event);
  }
 
  updateItem(listbox: ListBoxDirective, index: number, size: number): void {
    this._listbox = listbox;
    this.itemId = listbox.listboxId ? (listbox.listboxId + '_' + this.item.key) : undefined;
 
    this.ariaPosInSet = this.index + 1;
    this.ariaSetSize = size;
  }
 
  isFocused(): boolean {
    if (this._listbox) {
      return this._listbox.isFocused(this);
    } else {
      return false;
    }
  }
 
  focus(): void {
    this._listbox.focusItem(this);
  }
 
  focusNative(): void {
    this.el.nativeElement.focus();
  }
 
  scrollIntoView(): void {
    this.el.nativeElement.scrollIntoView({ block: 'nearest', inline: 'nearest' });
  }
 
}