1- import { Component , ViewChild , HostListener , ElementRef } from "@angular/core" ;
1+ import { Component , HostListener , ElementRef } from "@angular/core" ;
22import { Dialog } from "../dialog.component" ;
33import { position } from "../../utils/position" ;
4- import { isFocusInLastItem , isFocusInFirstItem } from "./../../common/tab.service" ;
4+ import { getFocusElementList , isFocusInLastItem , isFocusInFirstItem } from "./../../common/tab.service" ;
55import { I18n } from "./../../i18n/i18n.module" ;
66
77/**
@@ -17,7 +17,10 @@ import { I18n } from "./../../i18n/i18n.module";
1717 [ngClass]="{'bx--overflow-menu--flip': dialogConfig.flip}"
1818 role="menu"
1919 #dialog
20- class="bx--overflow-menu-options bx--overflow-menu-options--open">
20+ class="bx--overflow-menu-options bx--overflow-menu-options--open"
21+ role="menu"
22+ (focusout)="clickClose($event)"
23+ [attr.aria-label]="dialogConfig.menuLabel">
2124 <ng-template
2225 [ngTemplateOutlet]="dialogConfig.content"
2326 [ngTemplateOutletContext]="{overflowMenu: this}">
@@ -26,7 +29,6 @@ import { I18n } from "./../../i18n/i18n.module";
2629 `
2730} )
2831export class OverflowMenuPane extends Dialog {
29- @ViewChild ( "dialog" ) dialog ;
3032
3133 constructor ( protected elementRef : ElementRef , protected i18n : I18n ) {
3234 super ( elementRef ) ;
@@ -46,18 +48,25 @@ export class OverflowMenuPane extends Dialog {
4648 return position . addOffset ( pos , - 20 , - 60 ) ;
4749 }
4850 return position . addOffset ( pos , - 20 , 60 ) ;
49- }
51+ } ;
5052
5153 if ( ! this . dialogConfig . menuLabel ) {
5254 this . dialogConfig . menuLabel = this . i18n . get ( ) . OVERFLOW_MENU . OVERFLOW ;
5355 }
5456
55- setTimeout ( ( ) => this . listItems ( ) [ 0 ] . focus ( ) ) ;
57+ setTimeout ( ( ) => {
58+ getFocusElementList ( this . elementRef . nativeElement ) . every ( button => {
59+ // Allows user to set tabindex to 0.
60+ if ( button . getAttribute ( "tabindex" ) === null ) {
61+ button . tabIndex = - 1 ;
62+ }
63+ } ) ;
64+ this . listItems ( ) [ 0 ] . focus ( ) ;
65+ } , 0 ) ;
5666 }
5767
5868 @HostListener ( "keydown" , [ "$event" ] )
5969 hostkeys ( event : KeyboardEvent ) {
60- this . escapeClose ( event ) ;
6170 const listItems = this . listItems ( ) ;
6271
6372 switch ( event . key ) {
@@ -92,10 +101,26 @@ export class OverflowMenuPane extends Dialog {
92101 event . preventDefault ( ) ;
93102 listItems [ listItems . length - 1 ] . focus ( ) ;
94103 break ;
104+
105+ case "Esc" : // IE specific value
106+ case "Escape" :
107+ event . stopImmediatePropagation ( ) ;
108+ this . doClose ( ) ;
109+ break ;
110+ }
111+ }
112+
113+ clickClose ( event ) {
114+ // Opens menu when clicking on the menu button and stays open while navigating through the options
115+ if ( this . dialogConfig . parentRef . nativeElement . firstChild . contains ( event . target ) ||
116+ this . listItems ( ) . some ( button => button === event . relatedTarget ) ||
117+ event . type === "focusout" && event . relatedTarget === this . dialogConfig . parentRef . nativeElement ) {
118+ return ;
95119 }
120+ this . doClose ( ) ;
96121 }
97122
98123 private listItems ( ) {
99- return Array . from < any > ( this . dialog . nativeElement . querySelectorAll ( ".bx--overflow-menu-options__btn:not([disabled])" ) ) ;
124+ return Array . from < any > ( this . elementRef . nativeElement . querySelectorAll ( ".bx--overflow-menu-options__btn:not([disabled])" ) ) ;
100125 }
101126}
0 commit comments