fix(menu): incorrectly styling keyboard focus, if trigger is right clicked before opening (#13136)

Currently `mat-menu` displays focus indication only if it has been opened by keyboard. We detect how the menu was opened using a `mousedown` event. The issue comes from the fact that `mousedown` also fires for right or middle button clicks, event though a subsequent `click` won't fire, which will throw off our detection if the user opens the menu with their keyboard afterwards. These changes add a check that ensures that only left button clicks are considered as opening.
This commit is contained in:
Kristiyan Kostadinov
2018-10-02 22:30:45 +02:00
committed by vivian-hu
parent ff23527b47
commit 730e6a30a1
2 changed files with 30 additions and 3 deletions
+3 -1
View File
@@ -454,7 +454,9 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
/** Handles mouse presses on the trigger. */
_handleMousedown(event: MouseEvent): void {
if (!isFakeMousedownFromScreenReader(event)) {
this._openedByMouse = true;
// Since right or middle button clicks won't trigger the `click` event,
// we shouldn't consider the menu as opened by mouse in those cases.
this._openedByMouse = event.button === 0;
// Since clicking on the trigger won't close the menu if it opens a sub-menu,
// we should prevent focus from moving onto it via click to avoid the
+27 -2
View File
@@ -208,7 +208,7 @@ describe('MatMenu', () => {
fixture.detectChanges();
const triggerEl = fixture.componentInstance.triggerEl.nativeElement;
dispatchFakeEvent(triggerEl, 'mousedown');
dispatchMouseEvent(triggerEl, 'mousedown');
triggerEl.click();
fixture.detectChanges();
patchElementFocus(triggerEl);
@@ -222,6 +222,31 @@ describe('MatMenu', () => {
focusMonitor.stopMonitoring(triggerEl);
}));
it('should set proper focus origin when right clicking on trigger, before opening by keyboard',
fakeAsync(() => {
const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
fixture.detectChanges();
const triggerEl = fixture.componentInstance.triggerEl.nativeElement;
patchElementFocus(triggerEl);
focusMonitor.monitor(triggerEl, false);
// Trigger a fake right click.
dispatchEvent(triggerEl, createMouseEvent('mousedown', 50, 100, 2));
// A click without a left button mousedown before it is considered a keyboard open.
triggerEl.click();
fixture.detectChanges();
fixture.componentInstance.trigger.closeMenu();
fixture.detectChanges();
tick(500);
fixture.detectChanges();
expect(triggerEl.classList).toContain('cdk-program-focused');
focusMonitor.stopMonitoring(triggerEl);
}));
it('should close the menu when pressing ESCAPE', fakeAsync(() => {
const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
fixture.detectChanges();
@@ -347,7 +372,7 @@ describe('MatMenu', () => {
const triggerEl = fixture.componentInstance.triggerEl.nativeElement;
dispatchFakeEvent(triggerEl, 'mousedown');
dispatchMouseEvent(triggerEl, 'mousedown');
triggerEl.click();
fixture.detectChanges();
tick(500);