UNPKG

igniteui-angular-sovn

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

135 lines (124 loc) 4.15 kB
import { Directive, Optional, Self, Input, HostListener, Inject } from '@angular/core'; import { IGX_DROPDOWN_BASE } from './drop-down.common'; import { IDropDownNavigationDirective } from './drop-down.common'; import { IgxDropDownBaseDirective } from './drop-down.base'; import { DropDownActionKey } from './drop-down.common'; /** * Navigation Directive that handles keyboard events on its host and controls a targeted IgxDropDownBaseDirective component */ @Directive({ selector: '[igxDropDownItemNavigation]', standalone: true }) export class IgxDropDownItemNavigationDirective implements IDropDownNavigationDirective { protected _target: IgxDropDownBaseDirective = null; constructor(@Self() @Optional() @Inject(IGX_DROPDOWN_BASE) public dropdown: IgxDropDownBaseDirective) { } /** * Gets the target of the navigation directive; * * ```typescript * // Get * export class MyComponent { * ... * @ContentChild(IgxDropDownNavigationDirective) * navDirective: IgxDropDownNavigationDirective = null * ... * const navTarget: IgxDropDownBaseDirective = navDirective.navTarget * } * ``` */ public get target(): IgxDropDownBaseDirective { return this._target; } /** * Sets the target of the navigation directive; * If no valid target is passed, it falls back to the drop down context * * ```html * <!-- Set --> * <input [igxDropDownItemNavigation]="dropdown" /> * ... * <igx-drop-down #dropdown> * ... * </igx-drop-down> * ``` */ @Input('igxDropDownItemNavigation') public set target(target: IgxDropDownBaseDirective) { this._target = target ? target : this.dropdown; } /** * Captures keydown events and calls the appropriate handlers on the target component */ @HostListener('keydown', ['$event']) public handleKeyDown(event: KeyboardEvent) { if (event) { const key = event.key.toLowerCase(); if (!this.target.collapsed) { // If dropdown is opened const navKeys = ['esc', 'escape', 'enter', 'space', 'spacebar', ' ', 'arrowup', 'up', 'arrowdown', 'down', 'home', 'end']; if (navKeys.indexOf(key) === -1) { // If key has appropriate function in DD return; } event.preventDefault(); event.stopPropagation(); } else { // If dropdown is closed, do nothing return; } switch (key) { case 'esc': case 'escape': this.target.onItemActionKey(DropDownActionKey.ESCAPE, event); break; case 'enter': this.target.onItemActionKey(DropDownActionKey.ENTER, event); break; case 'space': case 'spacebar': case ' ': this.target.onItemActionKey(DropDownActionKey.SPACE, event); break; case 'arrowup': case 'up': this.onArrowUpKeyDown(); break; case 'arrowdown': case 'down': this.onArrowDownKeyDown(); break; case 'home': this.onHomeKeyDown(); break; case 'end': this.onEndKeyDown(); break; default: return; } } } /** * Navigates to previous item */ public onArrowDownKeyDown() { this.target.navigateNext(); } /** * Navigates to previous item */ public onArrowUpKeyDown() { this.target.navigatePrev(); } /** * Navigates to target's last item */ public onEndKeyDown() { this.target.navigateLast(); } /** * Navigates to target's first item */ public onHomeKeyDown() { this.target.navigateFirst(); } }