@visa/nova-angular
Version:
Visa Product Design System Nova Angular library
73 lines • 11.1 kB
JavaScript
/**
* Copyright (c) 2025 Visa, Inc.
*
* 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkLWFycm93LWtleXMuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9ub3ZhLWxpYi9zcmMvbGliL191dGlsaXRpZXMvYW5ndWxhci1zcGVjaWZpYy1kaXJlY3RpdmVzL2FkZC1hcnJvdy1rZXlzLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0lBZUk7QUFDSixPQUFPLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQWEsZ0JBQWdCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkcsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDcEYsT0FBTyxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxZQUFZLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNySCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7OztBQU14RCxNQUFNLE9BQU8scUJBQXFCO0lBRWhDLFlBQ1UsY0FBOEIsRUFDOUIsZUFBaUM7UUFEakMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLG9CQUFlLEdBQWYsZUFBZSxDQUFrQjtRQUgzQyx3QkFBbUIsR0FBWSxLQUFLLENBQUM7UUFTckMsZUFBVSxHQUE0QixFQUFFLENBQUM7UUFKdkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxlQUFlLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBS0Qsa0JBQWtCO1FBQ2hCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN2QyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRXBGLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUEyQixFQUFFLEtBQWEsRUFBRSxFQUFFO2dCQUNyRSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYTtvQkFBRSxPQUFPO2dCQUMvQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUk7Z0JBQ2pCLDZEQUE2RDtnQkFDN0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsU0FBUyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7b0JBQy9ELElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxVQUFVLEVBQUUsQ0FBQzt3QkFDN0IsT0FBTztvQkFDVCxDQUFDO29CQUNELDZEQUE2RDtvQkFDN0QsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLGNBQWMsSUFBSSxLQUFLLENBQUMsR0FBRyxLQUFLLGVBQWUsRUFBRSxDQUFDO3dCQUNsRSxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7d0JBQ3ZCLE1BQU0sUUFBUSxHQUFHLEtBQUssR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUN0RyxRQUFRLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDcEMsQ0FBQzt5QkFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssWUFBWSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssY0FBYyxFQUFFLENBQUM7d0JBQ3RFLDhEQUE4RDt3QkFDOUQsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO3dCQUN2QixNQUFNLFFBQVEsR0FBRyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQzt3QkFDeEcsUUFBUSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQ3BDLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7K0dBeENVLHFCQUFxQjttR0FBckIscUJBQXFCLGlHQVNmLHFCQUFxQjs7NEZBVDNCLHFCQUFxQjtrQkFKakMsU0FBUzttQkFBQztvQkFDVCxVQUFVLEVBQUUsSUFBSTtvQkFDaEIsUUFBUSxFQUFFLGlCQUFpQjtpQkFDNUI7a0hBVWdFLEtBQUs7c0JBQW5FLGVBQWU7dUJBQUMscUJBQXFCLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgICAgICAgICAgICAgQ29weXJpZ2h0IChjKSAyMDI1IFZpc2EsIEluYy5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqKi9cbmltcG9ydCB7IENvbnRlbnRDaGlsZHJlbiwgRGlyZWN0aXZlLCBRdWVyeUxpc3QsIFJlbmRlcmVyMiwgUmVuZGVyZXJGYWN0b3J5MiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRHJvcGRvd25JdGVtRGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vZHJvcGRvd24taXRlbS9kcm9wZG93bi1pdGVtLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBET1dOX0FSUk9XX0tFWSwgRVNDQVBFX0tFWSwgTEVGVF9BUlJPV19LRVksIFJJR0hUX0FSUk9XX0tFWSwgVVBfQVJST1dfS0VZIH0gZnJvbSAnLi4vLi4vbm92YS1saWIuY29uc3RhbnRzJztcbmltcG9ydCB7IE5vdmFMaWJTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vbm92YS1saWIuc2VydmljZSc7XG5cbkBEaXJlY3RpdmUoe1xuICBzdGFuZGFsb25lOiB0cnVlLFxuICBzZWxlY3RvcjogJ1t2QWRkQXJyb3dLZXlzXSdcbn0pXG5leHBvcnQgY2xhc3MgQWRkQXJyb3dLZXlzRGlyZWN0aXZlIHtcbiAgcmVtb3ZlVGFiTmF2aWdhdGlvbjogYm9vbGVhbiA9IGZhbHNlO1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG5vdmFMaWJTZXJ2aWNlOiBOb3ZhTGliU2VydmljZSxcbiAgICBwcml2YXRlIHJlbmRlcmVyRmFjdG9yeTogUmVuZGVyZXJGYWN0b3J5MlxuICApIHtcbiAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXJGYWN0b3J5LmNyZWF0ZVJlbmRlcmVyKG51bGwsIG51bGwpO1xuICB9XG4gIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMjtcbiAgQENvbnRlbnRDaGlsZHJlbihEcm9wZG93bkl0ZW1EaXJlY3RpdmUsIHsgZGVzY2VuZGFudHM6IHRydWUgfSkgaXRlbXM6IFF1ZXJ5TGlzdDxEcm9wZG93bkl0ZW1EaXJlY3RpdmU+O1xuICBpdGVtc0FycmF5OiBEcm9wZG93bkl0ZW1EaXJlY3RpdmVbXSA9IFtdO1xuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICB0aGlzLml0ZW1zQXJyYXkgPSB0aGlzLml0ZW1zLnRvQXJyYXkoKTtcbiAgICB0aGlzLml0ZW1zQXJyYXkgPSB0aGlzLml0ZW1zQXJyYXkuZmlsdGVyKChpdGVtKSA9PiAhaXRlbS5lbC5uYXRpdmVFbGVtZW50LmRpc2FibGVkKTtcblxuICAgIGlmICh0aGlzLml0ZW1zQXJyYXk/Lmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuaXRlbXNBcnJheS5mb3JFYWNoKChpdGVtOiBEcm9wZG93bkl0ZW1EaXJlY3RpdmUsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgaWYgKCFpdGVtLmVsIHx8ICFpdGVtLmVsLm5hdGl2ZUVsZW1lbnQpIHJldHVybjtcbiAgICAgICAgaXRlbS5saXN0ZW5lcnMucHVzaChcbiAgICAgICAgICAvLyBmb3IgZWFjaCBidXR0b24sIGFkZCBhbiBldmVudCBsaXN0ZW5lciBmb3IgYXJyb3cgXCJrZXlkb3duXCJcbiAgICAgICAgICB0aGlzLnJlbmRlcmVyLmxpc3RlbihpdGVtLmVsLm5hdGl2ZUVsZW1lbnQsICdrZXlkb3duJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQua2V5ID09PSBFU0NBUEVfS0VZKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHJpZ2h0IGFuZCBkb3duIGFycm93IGtleXMgc2hvdWxkIGdvIHRvIG5leHQgZm9jdXNhYmxlIGl0ZW1cbiAgICAgICAgICAgIGlmIChldmVudC5rZXkgPT09IERPV05fQVJST1dfS0VZIHx8IGV2ZW50LmtleSA9PT0gUklHSFRfQVJST1dfS0VZKSB7XG4gICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgIGNvbnN0IG5leHRJdGVtID0gaW5kZXggKyAxIDwgdGhpcy5pdGVtc0FycmF5Lmxlbmd0aCA/IHRoaXMuaXRlbXNBcnJheVtpbmRleCArIDFdIDogdGhpcy5pdGVtc0FycmF5WzBdO1xuICAgICAgICAgICAgICBuZXh0SXRlbS5lbC5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gVVBfQVJST1dfS0VZIHx8IGV2ZW50LmtleSA9PT0gTEVGVF9BUlJPV19LRVkpIHtcbiAgICAgICAgICAgICAgLy8gbGVmdCBhbmQgdXAgYXJyb3cga2V5cyBzaG91bGQgZ28gdG8gcHJldmlvdXMgZm9jdXNhYmxlIGl0ZW1cbiAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgY29uc3QgbmV4dEl0ZW0gPSBpbmRleCAhPT0gMCA/IHRoaXMuaXRlbXNBcnJheVtpbmRleCAtIDFdIDogdGhpcy5pdGVtc0FycmF5W3RoaXMuaXRlbXNBcnJheS5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgICAgbmV4dEl0ZW0uZWwubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==