import { FocusableOption , FocusOrigin } from '@angular/cdk/a11y' ; import { Directive , ElementRef , HostListener , Input , OnDestroy , OnInit , Renderer2 } from '@angular/core' ; import { Subject } from 'rxjs' ; import { takeUntil } from 'rxjs/operators' ; import { FocusIndicator , FocusIndicatorService } from '../../../directives/accessibility/index' ; import { MenuItemType } from '../menu-item/menu-item-type.enum' ; import { MenuComponent } from '../menu/menu.component' ; @ Directive ( { selector : '[uxMenuTabbableItem]' , } ) export class MenuTabbableItemDirective implements OnInit , OnDestroy , FocusableOption { /** Define if this item is disabled or not */ @ Input ( ) disabled : boolean = false ; /** Indicate the type of the menu item */ readonly type : MenuItemType = MenuItemType . Default ; /** Store the focus indicator instance */ private _focusIndicator : FocusIndicator ; /** Automatically unsubscribe when directive is destroyed */ private _onDestroy$ = new Subject < void > ( ) ; constructor ( private readonly _menu , private readonly _elementRef , private readonly _focusIndicatorService , private readonly _renderer ) { } ngOnInit ( ) { this . _menu . _addItem ( this ) ; this . _focusIndicator = this . _focusIndicatorService . monitor ( this . _elementRef . nativeElement ) ; this . _menu . _activeItem$ . pipe ( takeUntil ( this . _onDestroy$ ) ) . subscribe ( item => this . setTabIndex ( item === this ) ) ; } ngOnDestroy ( ) { this . _onDestroy$ . next ( ) ; this . _onDestroy$ . complete ( ) ; this . _focusIndicator . destroy ( ) ; } /** Focus this item with a given origin */ focus ( origin ) { this . _focusIndicator . focus ( origin ) ; } /** This function is built into the CDK manager to allow jumping to items based on text content */ getLabel ( ) { return this . _elementRef . nativeElement . textContent . trim ( ) ; } /** Forward any keyboard events to the MenuComponent for accessibility */ @ HostListener ( 'keydown' , [ '$event' ] ) _onKeydown ( event ) { this . _menu . _onKeydown ( event ) ; } /** Update the tab index on this item */ private setTabIndex ( isTabbable ) { this . _renderer . setAttribute ( this . _elementRef . nativeElement , 'tabindex' , isTabbable ? '0' : '-1' ) ; } }