Skip to content

Commit c7a7b1e

Browse files
authored
fix(cdk-experimental/menu): ensure menu is closed out when clicking on an inline menu item (#20241)
Fixes an issue where clicking an item in an inline menu prevents any open popout menus from closing out.
1 parent bc91087 commit c7a7b1e

File tree

3 files changed

+41
-20
lines changed

3 files changed

+41
-20
lines changed

src/cdk-experimental/menu/menu-bar.spec.ts

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -740,10 +740,11 @@ describe('MenuBar', () => {
740740
});
741741

742742
describe('background click closeout', () => {
743-
let fixture: ComponentFixture<MenuBarWithMenus>;
743+
let fixture: ComponentFixture<MenuBarWithMenusAndInlineMenu>;
744744

745-
let menus: CdkMenu[];
745+
let popoutMenus: CdkMenu[];
746746
let triggers: CdkMenuItemTrigger[];
747+
let nativeInlineMenuItem: HTMLElement;
747748

748749
/** open the attached menu. */
749750
function openMenu() {
@@ -753,8 +754,9 @@ describe('MenuBar', () => {
753754

754755
/** set the menus and triggers arrays. */
755756
function grabElementsForTesting() {
756-
menus = fixture.componentInstance.menus.toArray();
757+
popoutMenus = fixture.componentInstance.menus.toArray().filter(el => !el._isInline());
757758
triggers = fixture.componentInstance.triggers.toArray();
759+
nativeInlineMenuItem = fixture.componentInstance.nativeInlineMenuItem.nativeElement;
758760
}
759761

760762
/** run change detection and, extract and set the rendered elements. */
@@ -766,77 +768,86 @@ describe('MenuBar', () => {
766768
beforeEach(async(() => {
767769
TestBed.configureTestingModule({
768770
imports: [CdkMenuModule],
769-
declarations: [MenuBarWithMenus],
771+
declarations: [MenuBarWithMenusAndInlineMenu],
770772
}).compileComponents();
771773
}));
772774

773775
beforeEach(() => {
774-
fixture = TestBed.createComponent(MenuBarWithMenus);
776+
fixture = TestBed.createComponent(MenuBarWithMenusAndInlineMenu);
775777
detectChanges();
776778
});
777779

778780
it('should close out all open menus when clicked outside the menu tree', () => {
779781
openMenu();
780-
expect(menus.length).toBe(1);
782+
expect(popoutMenus.length).toBe(1);
781783

782784
fixture.debugElement.query(By.css('#container')).nativeElement.click();
783785
detectChanges();
784786

785-
expect(menus.length).toBe(0);
787+
expect(popoutMenus.length).toBe(0);
786788
});
787789

788790
it('should not close open menus when clicking on a menu group', () => {
789791
openMenu();
790-
expect(menus.length).toBe(1);
792+
expect(popoutMenus.length).toBe(1);
791793

792794
const menuGroups = fixture.debugElement.queryAll(By.directive(CdkMenuGroup));
793795
menuGroups[2].nativeElement.click();
794796
detectChanges();
795797

796-
expect(menus.length).toBe(1);
798+
expect(popoutMenus.length).toBe(1);
797799
});
798800

799801
it('should not close open menus when clicking on a menu', () => {
800802
openMenu();
801-
expect(menus.length).toBe(1);
803+
expect(popoutMenus.length).toBe(1);
802804

803805
fixture.debugElement.query(By.directive(CdkMenu)).nativeElement.click();
804806
detectChanges();
805807

806-
expect(menus.length).toBe(1);
808+
expect(popoutMenus.length).toBe(1);
807809
});
808810

809811
it('should not close open menus when clicking on a menu bar', () => {
810812
openMenu();
811-
expect(menus.length).toBe(1);
813+
expect(popoutMenus.length).toBe(1);
812814

813815
fixture.debugElement.query(By.directive(CdkMenuBar)).nativeElement.click();
814816
detectChanges();
815817

816-
expect(menus.length).toBe(1);
818+
expect(popoutMenus.length).toBe(1);
817819
});
818820

819821
it('should not close when clicking on a CdkMenuItemCheckbox element', () => {
820822
openMenu();
821-
expect(menus.length).toBe(1);
823+
expect(popoutMenus.length).toBe(1);
822824

823825
fixture.debugElement.query(By.directive(CdkMenuItemCheckbox)).nativeElement.click();
824826
fixture.detectChanges();
825827

826-
expect(menus.length).toBe(1);
828+
expect(popoutMenus.length).toBe(1);
827829
});
828830

829831
it('should not close when clicking on a non-menu element inside menu', () => {
830832
openMenu();
831-
expect(menus.length).toBe(1);
833+
expect(popoutMenus.length).toBe(1);
832834

833835
fixture.debugElement.query(By.css('#inner-element')).nativeElement.click();
834836
detectChanges();
835837

836-
expect(menus.length)
838+
expect(popoutMenus.length)
837839
.withContext('menu should stay open if clicking on an inner span element')
838840
.toBe(1);
839841
});
842+
843+
it('should close the open menu when clicking on an inline menu item', () => {
844+
openMenu();
845+
846+
nativeInlineMenuItem.click();
847+
detectChanges();
848+
849+
expect(popoutMenus.length).toBe(0);
850+
});
840851
});
841852

842853
describe('Mouse handling', () => {
@@ -1171,10 +1182,16 @@ class MenuWithRadioButtons {
11711182
</div>
11721183
</ng-template>
11731184
</div>
1185+
1186+
<div cdkMenu>
1187+
<button #inline_menu_item cdkMenuItem></button>
1188+
</div>
11741189
`,
11751190
})
1176-
class MenuBarWithMenus {
1191+
class MenuBarWithMenusAndInlineMenu {
11771192
@ViewChildren(CdkMenu) menus: QueryList<CdkMenu>;
11781193

11791194
@ViewChildren(CdkMenuItemTrigger) triggers: QueryList<CdkMenuItemTrigger>;
1195+
1196+
@ViewChild('inline_menu_item') nativeInlineMenuItem: ElementRef;
11801197
}

src/cdk-experimental/menu/menu-bar.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,15 @@ import {MenuStack, MenuStackItem, FocusNext} from './menu-stack';
2929
import {getItemPointerEntries} from './item-pointer-entries';
3030

3131
/**
32-
* Check if the given element is part of the cdk menu module.
32+
* Whether the element is a menu bar or a popup menu.
3333
* @param target the element to check.
3434
* @return true if the given element is part of the menu module.
3535
*/
3636
function isMenuElement(target: Element) {
37-
return target.className.indexOf('cdk-menu') !== -1;
37+
return (
38+
target.classList.contains('cdk-menu-bar') ||
39+
(target.classList.contains('cdk-menu') && !target.classList.contains('cdk-menu-inline'))
40+
);
3841
}
3942

4043
/**

src/cdk-experimental/menu/menu.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import {getItemPointerEntries} from './item-pointer-entries';
5454
'[tabindex]': '_isInline() ? 0 : null',
5555
'role': 'menu',
5656
'class': 'cdk-menu',
57+
'[class.cdk-menu-inline]': '_isInline()',
5758
'[attr.aria-orientation]': 'orientation',
5859
},
5960
providers: [

0 commit comments

Comments
 (0)