|
|
@@ -13,6 +13,7 @@ import {
|
|
|
Component,
|
|
|
ContentChild,
|
|
|
ElementRef,
|
|
|
+ HostListener,
|
|
|
Input,
|
|
|
OnDestroy,
|
|
|
OnInit,
|
|
|
@@ -42,7 +43,11 @@ export type DropdownPosition = 'top-left' | 'top-right' | 'bottom-left' | 'botto
|
|
|
<ng-template #menu>
|
|
|
<div class="dropdown open">
|
|
|
<div class="dropdown-menu" [ngClass]="customClasses">
|
|
|
- <div class="dropdown-content-wrapper">
|
|
|
+ <div
|
|
|
+ class="dropdown-content-wrapper"
|
|
|
+ [cdkTrapFocus]="true"
|
|
|
+ [cdkTrapFocusAutoCapture]="true"
|
|
|
+ >
|
|
|
<ng-content></ng-content>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -56,10 +61,45 @@ export class DropdownMenuComponent implements AfterViewInit, OnInit, OnDestroy {
|
|
|
@Input('vdrPosition') private position: DropdownPosition = 'bottom-left';
|
|
|
@Input() customClasses: string;
|
|
|
@ViewChild('menu', { static: true }) private menuTemplate: TemplateRef<any>;
|
|
|
- private menuPortal: TemplatePortal<any>;
|
|
|
+ private menuPortal: TemplatePortal;
|
|
|
private overlayRef: OverlayRef;
|
|
|
private backdropClickSub: Subscription;
|
|
|
|
|
|
+ @HostListener('window:keydown.escape', ['$event'])
|
|
|
+ onEscapeKeydown(event: KeyboardEvent) {
|
|
|
+ if (this.dropdown.isOpen) {
|
|
|
+ if (this.overlayRef.overlayElement.contains(document.activeElement)) {
|
|
|
+ this.dropdown.toggleOpen();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @HostListener('window:keydown', ['$event'])
|
|
|
+ onArrowKey(event: KeyboardEvent) {
|
|
|
+ if (
|
|
|
+ this.dropdown.isOpen &&
|
|
|
+ document.activeElement instanceof HTMLElement &&
|
|
|
+ (event.key === 'ArrowDown' || event.key === 'ArrowUp')
|
|
|
+ ) {
|
|
|
+ const dropdownItems = Array.from(
|
|
|
+ this.overlayRef.overlayElement.querySelectorAll<HTMLElement>('.dropdown-item'),
|
|
|
+ );
|
|
|
+ const currentIndex = dropdownItems.indexOf(document.activeElement);
|
|
|
+ if (currentIndex === -1) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (event.key === 'ArrowDown') {
|
|
|
+ const nextItem = dropdownItems[(currentIndex + 1) % dropdownItems.length];
|
|
|
+ nextItem.focus();
|
|
|
+ }
|
|
|
+ if (event.key === 'ArrowUp') {
|
|
|
+ const previousItem =
|
|
|
+ dropdownItems[(currentIndex - 1 + dropdownItems.length) % dropdownItems.length];
|
|
|
+ previousItem.focus();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
constructor(
|
|
|
private overlay: Overlay,
|
|
|
private viewContainerRef: ViewContainerRef,
|