UNPKG

@visa/nova-angular

Version:

Visa Product Design System Nova Angular library

73 lines 11.1 kB
/** * © 2025 Visa * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **/ import { ContentChildren, Directive, QueryList, RendererFactory2 } from '@angular/core'; import { DropdownItemDirective } from '../../dropdown-item/dropdown-item.directive'; import { DOWN_ARROW_KEY, ESCAPE_KEY, LEFT_ARROW_KEY, RIGHT_ARROW_KEY, UP_ARROW_KEY } from '../../nova-lib.constants'; import { NovaLibService } from '../../nova-lib.service'; import * as i0 from "@angular/core"; import * as i1 from "../../nova-lib.service"; export class AddArrowKeysDirective { constructor(novaLibService, rendererFactory) { this.novaLibService = novaLibService; this.rendererFactory = rendererFactory; this.removeTabNavigation = false; this.itemsArray = []; this.renderer = rendererFactory.createRenderer(null, null); } ngAfterContentInit() { this.itemsArray = this.items.toArray(); this.itemsArray = this.itemsArray.filter((item) => !item.el.nativeElement.disabled); if (this.itemsArray?.length > 0) { this.itemsArray.forEach((item, index) => { if (!item.el || !item.el.nativeElement) return; item.listeners.push( // for each button, add an event listener for arrow "keydown" this.renderer.listen(item.el.nativeElement, 'keydown', (event) => { if (event.key === ESCAPE_KEY) { return; } // right and down arrow keys should go to next focusable item if (event.key === DOWN_ARROW_KEY || event.key === RIGHT_ARROW_KEY) { event.preventDefault(); const nextItem = index + 1 < this.itemsArray.length ? this.itemsArray[index + 1] : this.itemsArray[0]; nextItem.el.nativeElement.focus(); } else if (event.key === UP_ARROW_KEY || event.key === LEFT_ARROW_KEY) { // left and up arrow keys should go to previous focusable item event.preventDefault(); const nextItem = index !== 0 ? this.itemsArray[index - 1] : this.itemsArray[this.itemsArray.length - 1]; nextItem.el.nativeElement.focus(); } })); }); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AddArrowKeysDirective, deps: [{ token: i1.NovaLibService }, { token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: AddArrowKeysDirective, isStandalone: true, selector: "[vAddArrowKeys]", queries: [{ propertyName: "items", predicate: DropdownItemDirective, descendants: true }], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AddArrowKeysDirective, decorators: [{ type: Directive, args: [{ standalone: true, selector: '[vAddArrowKeys]' }] }], ctorParameters: () => [{ type: i1.NovaLibService }, { type: i0.RendererFactory2 }], propDecorators: { items: [{ type: ContentChildren, args: [DropdownItemDirective, { descendants: true }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkLWFycm93LWtleXMuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9ub3ZhLWxpYi9zcmMvbGliL191dGlsaXRpZXMvYW5ndWxhci1zcGVjaWZpYy1kaXJlY3RpdmVzL2FkZC1hcnJvdy1rZXlzLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0lBZUk7QUFDSixPQUFPLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQWEsZ0JBQWdCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkcsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDcEYsT0FBTyxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxZQUFZLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNySCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7OztBQU14RCxNQUFNLE9BQU8scUJBQXFCO0lBRWhDLFlBQ1UsY0FBOEIsRUFDOUIsZUFBaUM7UUFEakMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLG9CQUFlLEdBQWYsZUFBZSxDQUFrQjtRQUgzQyx3QkFBbUIsR0FBWSxLQUFLLENBQUM7UUFTckMsZUFBVSxHQUE0QixFQUFFLENBQUM7UUFKdkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxlQUFlLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBS0Qsa0JBQWtCO1FBQ2hCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN2QyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRXBGLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUEyQixFQUFFLEtBQWEsRUFBRSxFQUFFO2dCQUNyRSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYTtvQkFBRSxPQUFPO2dCQUMvQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUk7Z0JBQ2pCLDZEQUE2RDtnQkFDN0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsU0FBUyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7b0JBQy9ELElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxVQUFVLEVBQUUsQ0FBQzt3QkFDN0IsT0FBTztvQkFDVCxDQUFDO29CQUNELDZEQUE2RDtvQkFDN0QsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLGNBQWMsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLGVBQWUsRUFBRSxDQUFDO3dCQUNsRSxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7d0JBQ3ZCLE1BQU0sUUFBUSxHQUFHLEtBQUssR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUN0RyxRQUFRLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDcEMsQ0FBQzt5QkFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssWUFBWSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssY0FBYyxFQUFFLENBQUM7d0JBQ3RFLDhEQUE4RDt3QkFDOUQsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO3dCQUN2QixNQUFNLFFBQVEsR0FBRyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQzt3QkFDeEcsUUFBUSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQ3BDLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7K0dBeENVLHFCQUFxQjttR0FBckIscUJBQXFCLGlHQVNmLHFCQUFxQjs7NEZBVDNCLHFCQUFxQjtrQkFKakMsU0FBUzttQkFBQztvQkFDVCxVQUFVLEVBQUUsSUFBSTtvQkFDaEIsUUFBUSxFQUFFLGlCQUFpQjtpQkFDNUI7a0hBVWdFLEtBQUs7c0JBQW5FLGVBQWU7dUJBQUMscUJBQXFCLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgICAgICAgICAgICAgwqkgMjAyNSBWaXNhXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKiovXG5pbXBvcnQgeyBDb250ZW50Q2hpbGRyZW4sIERpcmVjdGl2ZSwgUXVlcnlMaXN0LCBSZW5kZXJlcjIsIFJlbmRlcmVyRmFjdG9yeTIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERyb3Bkb3duSXRlbURpcmVjdGl2ZSB9IGZyb20gJy4uLy4uL2Ryb3Bkb3duLWl0ZW0vZHJvcGRvd24taXRlbS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgRE9XTl9BUlJPV19LRVksIEVTQ0FQRV9LRVksIExFRlRfQVJST1dfS0VZLCBSSUdIVF9BUlJPV19LRVksIFVQX0FSUk9XX0tFWSB9IGZyb20gJy4uLy4uL25vdmEtbGliLmNvbnN0YW50cyc7XG5pbXBvcnQgeyBOb3ZhTGliU2VydmljZSB9IGZyb20gJy4uLy4uL25vdmEtbGliLnNlcnZpY2UnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgc2VsZWN0b3I6ICdbdkFkZEFycm93S2V5c10nXG59KVxuZXhwb3J0IGNsYXNzIEFkZEFycm93S2V5c0RpcmVjdGl2ZSB7XG4gIHJlbW92ZVRhYk5hdmlnYXRpb246IGJvb2xlYW4gPSBmYWxzZTtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBub3ZhTGliU2VydmljZTogTm92YUxpYlNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZW5kZXJlckZhY3Rvcnk6IFJlbmRlcmVyRmFjdG9yeTJcbiAgKSB7XG4gICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyRmFjdG9yeS5jcmVhdGVSZW5kZXJlcihudWxsLCBudWxsKTtcbiAgfVxuICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjI7XG4gIEBDb250ZW50Q2hpbGRyZW4oRHJvcGRvd25JdGVtRGlyZWN0aXZlLCB7IGRlc2NlbmRhbnRzOiB0cnVlIH0pIGl0ZW1zOiBRdWVyeUxpc3Q8RHJvcGRvd25JdGVtRGlyZWN0aXZlPjtcbiAgaXRlbXNBcnJheTogRHJvcGRvd25JdGVtRGlyZWN0aXZlW10gPSBbXTtcblxuICBuZ0FmdGVyQ29udGVudEluaXQoKSB7XG4gICAgdGhpcy5pdGVtc0FycmF5ID0gdGhpcy5pdGVtcy50b0FycmF5KCk7XG4gICAgdGhpcy5pdGVtc0FycmF5ID0gdGhpcy5pdGVtc0FycmF5LmZpbHRlcigoaXRlbSkgPT4gIWl0ZW0uZWwubmF0aXZlRWxlbWVudC5kaXNhYmxlZCk7XG5cbiAgICBpZiAodGhpcy5pdGVtc0FycmF5Py5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLml0ZW1zQXJyYXkuZm9yRWFjaCgoaXRlbTogRHJvcGRvd25JdGVtRGlyZWN0aXZlLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGlmICghaXRlbS5lbCB8fCAhaXRlbS5lbC5uYXRpdmVFbGVtZW50KSByZXR1cm47XG4gICAgICAgIGl0ZW0ubGlzdGVuZXJzLnB1c2goXG4gICAgICAgICAgLy8gZm9yIGVhY2ggYnV0dG9uLCBhZGQgYW4gZXZlbnQgbGlzdGVuZXIgZm9yIGFycm93IFwia2V5ZG93blwiXG4gICAgICAgICAgdGhpcy5yZW5kZXJlci5saXN0ZW4oaXRlbS5lbC5uYXRpdmVFbGVtZW50LCAna2V5ZG93bicsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmtleSA9PT0gRVNDQVBFX0tFWSkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyByaWdodCBhbmQgZG93biBhcnJvdyBrZXlzIHNob3VsZCBnbyB0byBuZXh0IGZvY3VzYWJsZSBpdGVtXG4gICAgICAgICAgICBpZiAoZXZlbnQua2V5ID09PSBET1dOX0FSUk9XX0tFWSB8fCBldmVudC5rZXkgPT09IFJJR0hUX0FSUk9XX0tFWSkge1xuICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICBjb25zdCBuZXh0SXRlbSA9IGluZGV4ICsgMSA8IHRoaXMuaXRlbXNBcnJheS5sZW5ndGggPyB0aGlzLml0ZW1zQXJyYXlbaW5kZXggKyAxXSA6IHRoaXMuaXRlbXNBcnJheVswXTtcbiAgICAgICAgICAgICAgbmV4dEl0ZW0uZWwubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IFVQX0FSUk9XX0tFWSB8fCBldmVudC5rZXkgPT09IExFRlRfQVJST1dfS0VZKSB7XG4gICAgICAgICAgICAgIC8vIGxlZnQgYW5kIHVwIGFycm93IGtleXMgc2hvdWxkIGdvIHRvIHByZXZpb3VzIGZvY3VzYWJsZSBpdGVtXG4gICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgIGNvbnN0IG5leHRJdGVtID0gaW5kZXggIT09IDAgPyB0aGlzLml0ZW1zQXJyYXlbaW5kZXggLSAxXSA6IHRoaXMuaXRlbXNBcnJheVt0aGlzLml0ZW1zQXJyYXkubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgIG5leHRJdGVtLmVsLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG4iXX0=