Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(menu): keyboard controls not working if all items are disabled #16572

Merged
merged 1 commit into from
Aug 27, 2019

Conversation

crisbeto
Copy link
Member

Currently we depend on focusFirstItem to bring focus into the menu, however if all the items are disabled, focus will stay on the trigger and the user won't get feedback that something has happened. Furthermore, the keyboard shortcuts that are implemented in the menu won't work either, because the keyboard event listener is on the menu.

These changes work around the issue by setting focus on the role="menu" if none of the items were focusable.

Fixes #16565.

@crisbeto crisbeto added P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent Accessibility This issue is related to accessibility (a11y) target: patch This PR is targeted for the next patch release labels Jul 19, 2019
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Jul 19, 2019
Currently we depend on `focusFirstItem` to bring focus into the menu, however if all the items are disabled, focus will stay on the trigger and the user won't get feedback that something has happened. Furthermore, the keyboard shortcuts that are implemented in the menu won't work either, because the keyboard event listener is on the menu.

These changes work around the issue by setting focus on the `role="menu"` if none of the items were focusable.

Fixes angular#16565.
@crisbeto crisbeto force-pushed the 16565.disabled-menu-item-keyboard branch from f4da270 to f0d6f06 Compare July 19, 2019 18:31
// the items and walking up the DOM.
while (element) {
if (element.getAttribute('role') === 'menu') {
element.focus();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: it felt a little weird to have this logic here since the method is called focusFirstItem, however the alternative is to do it inside the menu trigger which would require another method to be added to the MatMenuPanel interface which will increase the API surface. Furthermore, doing it through the trigger may no be very reliable, because we'd need to check if the document.activeElement is inside the menu and some browsers move focus asynchronously.

@@ -762,6 +762,44 @@ describe('MatMenu', () => {
flush();
}));

it('should respect the DOM order, rather than insertion order, when moving focus using ' +
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ported this test over, because it got in through a very old PR that got in recently which was opened before the MDC menu existed.

Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, though we should also update the docs to recommend people disable the menu if all the options would be disabled

@jelbourn jelbourn added pr: lgtm action: merge The PR is ready for merge by the caretaker labels Aug 21, 2019
@jelbourn jelbourn merged commit d3f63a3 into angular:master Aug 27, 2019
mmalerba pushed a commit to mmalerba/components that referenced this pull request Aug 27, 2019
…ngular#16572)

Currently we depend on `focusFirstItem` to bring focus into the menu, however if all the items are disabled, focus will stay on the trigger and the user won't get feedback that something has happened. Furthermore, the keyboard shortcuts that are implemented in the menu won't work either, because the keyboard event listener is on the menu.

These changes work around the issue by setting focus on the `role="menu"` if none of the items were focusable.

Fixes angular#16565.
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 27, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Accessibility This issue is related to accessibility (a11y) action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Menu with disabled options doesn't close on ESC
3 participants