Skip to content

Commit 31a0289

Browse files
committed
fix(material/menu): unable to move focus from inside opened event
We move focus inside the menu after we've dispatched the `menuOpened` event which means that we'll override any focus that the consumer may have set inside the handler. These changes fix the issue by changing the order. Fixes #20965.
1 parent 4699f30 commit 31a0289

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

src/material-experimental/mdc-menu/menu.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,21 @@ describe('MDC-based MatMenu', () => {
994994
.toBe(overlayContainerElement.querySelector('.mat-mdc-menu-panel'));
995995
}));
996996

997+
it('should be able to move focus inside the `open` event', fakeAsync(() => {
998+
const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
999+
fixture.detectChanges();
1000+
1001+
fixture.componentInstance.trigger.menuOpened.subscribe(() => {
1002+
(document.querySelectorAll('.mat-mdc-menu-panel [mat-menu-item]')[3] as HTMLElement).focus();
1003+
});
1004+
fixture.componentInstance.trigger.openMenu();
1005+
fixture.detectChanges();
1006+
tick(500);
1007+
1008+
const items = document.querySelectorAll('.mat-mdc-menu-panel [mat-menu-item]');
1009+
expect(document.activeElement).toBe(items[3], 'Expected fourth item to be focused');
1010+
}));
1011+
9971012
describe('lazy rendering', () => {
9981013
it('should be able to render the menu content lazily', fakeAsync(() => {
9991014
const fixture = createComponent(SimpleLazyMenu);

src/material/menu/menu-trigger.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,8 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
331331
this.menu.parentMenu = this.triggersSubmenu() ? this._parentMaterialMenu : undefined;
332332
this.menu.direction = this.dir;
333333
this._setMenuElevation();
334-
this._setIsMenuOpen(true);
335334
this.menu.focusFirstItem(this._openedBy || 'program');
335+
this._setIsMenuOpen(true);
336336
}
337337

338338
/** Updates the menu elevation based on the amount of parent menus that it has. */

src/material/menu/menu.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,21 @@ describe('MatMenu', () => {
932932
expect(document.activeElement).toBe(overlayContainerElement.querySelector('.mat-menu-panel'));
933933
}));
934934

935+
it('should be able to move focus inside the `open` event', fakeAsync(() => {
936+
const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
937+
fixture.detectChanges();
938+
939+
fixture.componentInstance.trigger.menuOpened.subscribe(() => {
940+
(document.querySelectorAll('.mat-menu-panel [mat-menu-item]')[3] as HTMLElement).focus();
941+
});
942+
fixture.componentInstance.trigger.openMenu();
943+
fixture.detectChanges();
944+
tick(500);
945+
946+
const items = document.querySelectorAll('.mat-menu-panel [mat-menu-item]');
947+
expect(document.activeElement).toBe(items[3], 'Expected fourth item to be focused');
948+
}));
949+
935950
describe('lazy rendering', () => {
936951
it('should be able to render the menu content lazily', fakeAsync(() => {
937952
const fixture = createComponent(SimpleLazyMenu);

0 commit comments

Comments
 (0)