import { FocusKeyManager } from '@angular/cdk/a11y' ; import { Injectable , OnDestroy , QueryList } from '@angular/core' ; import { Observable , Subject } from 'rxjs' ; import { map , takeUntil } from 'rxjs/operators' ; import { tick } from '../../../common/operators/index' ; import { PageHeaderNavigationItemComponent } from './navigation-item/navigation-item.component' ; @ Injectable ( ) export class PageHeaderNavigationService implements OnDestroy { /** Store an instance of the focus key manager */ private _focusManager : FocusKeyManager < PageHeaderNavigationItemComponent > ; /** Store the query list */ private _items : QueryList < PageHeaderNavigationItemComponent > ; /**
     * Emit when focus changes. We can't directly use the FocusKeyManager
     * `change` observable as it cannot be instantiate until after the view
     * has been instantiated.
     */ private _onChange = new Subject < void > ( ) ; /** Unsubscribe on destroy */ private _onDestroy = new Subject < void > ( ) ; ngOnDestroy ( ) { this . _onDestroy . next ( ) ; this . _onDestroy . complete ( ) ; } /** Make menu items navigable using arrow keys */ initialize ( items ) { this . _items = items ; this . _focusManager = new FocusKeyManager < PageHeaderNavigationItemComponent > ( items ) . withHorizontalOrientation ( 'ltr' ) ; this . _focusManager . change . pipe ( takeUntil ( this . _onDestroy ) ) . subscribe ( ( ) => this . _onChange . next ( ) ) ; this . _focusManager . updateActiveItem ( 0 ) ; this . _items . changes . subscribe ( ( ) => { if ( this . _items . length > 0 && this . _items . toArray ( ) . indexOf ( this . _focusManager . activeItem ) === - 1 ) { this . _focusManager . updateActiveItem ( 0 ) ; } } ) ; this . _onChange . next ( ) ; } /** Listen for keyboard events */ onKeydown ( event ) { this . _focusManager . onKeydown ( event ) ; } /** Get the tab index for this item as an observable */ getTabIndex ( item ) { return this . _onChange . pipe ( map ( ( ) => this . getItemTabIndex ( item ) ) , tick ( ) , takeUntil ( this . _onDestroy ) ) ; } /** Determine the tab index of a given item */ private getItemTabIndex ( item ) { if ( ! this . _items ) { return 0 ; } const index = this . _items . toArray ( ) . indexOf ( item ) ; return index === this . _focusManager . activeItemIndex ? 0 : - 1 ; } }