Skip to content

Commit 3f1588f

Browse files
crisbetojelbourn
authored andcommittedDec 3, 2018
fix(menu): allow alternate roles to be set on menu item (#14165)
Based on the a11y guidelines, the menu items can have the `menuitemradio` and `menuitemcheckbox` roles, instead of `menuitem`. These changes allow for the consumer to set an alternate role. Fixes #14163.
1 parent c552504 commit 3f1588f

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed
 

‎src/lib/menu/menu-item.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
ViewEncapsulation,
1616
Inject,
1717
Optional,
18+
Input,
1819
} from '@angular/core';
1920
import {
2021
CanDisable, CanDisableCtor,
@@ -42,7 +43,7 @@ export const _MatMenuItemMixinBase: CanDisableRippleCtor & CanDisableCtor & type
4243
exportAs: 'matMenuItem',
4344
inputs: ['disabled', 'disableRipple'],
4445
host: {
45-
'role': 'menuitem',
46+
'[attr.role]': 'role',
4647
'class': 'mat-menu-item',
4748
'[class.mat-menu-item-highlighted]': '_highlighted',
4849
'[class.mat-menu-item-submenu-trigger]': '_triggersSubmenu',
@@ -59,6 +60,9 @@ export const _MatMenuItemMixinBase: CanDisableRippleCtor & CanDisableCtor & type
5960
export class MatMenuItem extends _MatMenuItemMixinBase
6061
implements FocusableOption, CanDisable, CanDisableRipple, OnDestroy {
6162

63+
/** ARIA role for the menu item. */
64+
@Input() role: 'menuitem' | 'menuitemradio' | 'menuitemcheckbox' = 'menuitem';
65+
6266
private _document: Document;
6367

6468
/** Stream that emits when the menu item is hovered. */

‎src/lib/menu/menu.spec.ts

+39
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,30 @@ describe('MatMenu', () => {
385385
expect(role).toBe('menu', 'Expected panel to have the "menu" role.');
386386
});
387387

388+
it('should set the "menuitem" role on the items by default', () => {
389+
const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
390+
fixture.detectChanges();
391+
fixture.componentInstance.trigger.openMenu();
392+
fixture.detectChanges();
393+
394+
const items = Array.from(overlayContainerElement.querySelectorAll('.mat-menu-item'));
395+
396+
expect(items.length).toBeGreaterThan(0);
397+
expect(items.every(item => item.getAttribute('role') === 'menuitem')).toBe(true);
398+
});
399+
400+
it('should be able to set an alternate role on the menu items', () => {
401+
const fixture = createComponent(MenuWithCheckboxItems);
402+
fixture.detectChanges();
403+
fixture.componentInstance.trigger.openMenu();
404+
fixture.detectChanges();
405+
406+
const items = Array.from(overlayContainerElement.querySelectorAll('.mat-menu-item'));
407+
408+
expect(items.length).toBeGreaterThan(0);
409+
expect(items.every(item => item.getAttribute('role') === 'menuitemcheckbox')).toBe(true);
410+
});
411+
388412
it('should not throw an error on destroy', () => {
389413
const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
390414
expect(fixture.destroy.bind(fixture)).not.toThrow();
@@ -2100,3 +2124,18 @@ class DynamicPanelMenu {
21002124
@ViewChild('one') firstMenu: MatMenu;
21012125
@ViewChild('two') secondMenu: MatMenu;
21022126
}
2127+
2128+
2129+
@Component({
2130+
template: `
2131+
<button [matMenuTriggerFor]="menu">Toggle menu</button>
2132+
2133+
<mat-menu #menu="matMenu">
2134+
<button mat-menu-item role="menuitemcheckbox" aria-checked="true">Checked</button>
2135+
<button mat-menu-item role="menuitemcheckbox" aria-checked="false">Not checked</button>
2136+
</mat-menu>
2137+
`
2138+
})
2139+
class MenuWithCheckboxItems {
2140+
@ViewChild(MatMenuTrigger) trigger: MatMenuTrigger;
2141+
}

0 commit comments

Comments
 (0)
Please sign in to comment.