mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
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.
This commit is contained in:
committed by
Jeremy Elbourn
parent
f00c8a82d0
commit
18ef94f342
@@ -15,6 +15,7 @@ import {
|
||||
ViewEncapsulation,
|
||||
Inject,
|
||||
Optional,
|
||||
Input,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
CanDisable, CanDisableCtor,
|
||||
@@ -42,7 +43,7 @@ export const _MatMenuItemMixinBase: CanDisableRippleCtor & CanDisableCtor & type
|
||||
exportAs: 'matMenuItem',
|
||||
inputs: ['disabled', 'disableRipple'],
|
||||
host: {
|
||||
'role': 'menuitem',
|
||||
'[attr.role]': 'role',
|
||||
'class': 'mat-menu-item',
|
||||
'[class.mat-menu-item-highlighted]': '_highlighted',
|
||||
'[class.mat-menu-item-submenu-trigger]': '_triggersSubmenu',
|
||||
@@ -59,6 +60,9 @@ export const _MatMenuItemMixinBase: CanDisableRippleCtor & CanDisableCtor & type
|
||||
export class MatMenuItem extends _MatMenuItemMixinBase
|
||||
implements FocusableOption, CanDisable, CanDisableRipple, OnDestroy {
|
||||
|
||||
/** ARIA role for the menu item. */
|
||||
@Input() role: 'menuitem' | 'menuitemradio' | 'menuitemcheckbox' = 'menuitem';
|
||||
|
||||
private _document: Document;
|
||||
|
||||
/** Stream that emits when the menu item is hovered. */
|
||||
|
||||
@@ -385,6 +385,30 @@ describe('MatMenu', () => {
|
||||
expect(role).toBe('menu', 'Expected panel to have the "menu" role.');
|
||||
});
|
||||
|
||||
it('should set the "menuitem" role on the items by default', () => {
|
||||
const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
|
||||
fixture.detectChanges();
|
||||
fixture.componentInstance.trigger.openMenu();
|
||||
fixture.detectChanges();
|
||||
|
||||
const items = Array.from(overlayContainerElement.querySelectorAll('.mat-menu-item'));
|
||||
|
||||
expect(items.length).toBeGreaterThan(0);
|
||||
expect(items.every(item => item.getAttribute('role') === 'menuitem')).toBe(true);
|
||||
});
|
||||
|
||||
it('should be able to set an alternate role on the menu items', () => {
|
||||
const fixture = createComponent(MenuWithCheckboxItems);
|
||||
fixture.detectChanges();
|
||||
fixture.componentInstance.trigger.openMenu();
|
||||
fixture.detectChanges();
|
||||
|
||||
const items = Array.from(overlayContainerElement.querySelectorAll('.mat-menu-item'));
|
||||
|
||||
expect(items.length).toBeGreaterThan(0);
|
||||
expect(items.every(item => item.getAttribute('role') === 'menuitemcheckbox')).toBe(true);
|
||||
});
|
||||
|
||||
it('should not throw an error on destroy', () => {
|
||||
const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
|
||||
expect(fixture.destroy.bind(fixture)).not.toThrow();
|
||||
@@ -2100,3 +2124,18 @@ class DynamicPanelMenu {
|
||||
@ViewChild('one') firstMenu: MatMenu;
|
||||
@ViewChild('two') secondMenu: MatMenu;
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<button [matMenuTriggerFor]="menu">Toggle menu</button>
|
||||
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item role="menuitemcheckbox" aria-checked="true">Checked</button>
|
||||
<button mat-menu-item role="menuitemcheckbox" aria-checked="false">Not checked</button>
|
||||
</mat-menu>
|
||||
`
|
||||
})
|
||||
class MenuWithCheckboxItems {
|
||||
@ViewChild(MatMenuTrigger) trigger: MatMenuTrigger;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user