Skip to content

Commit 010753d

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 3c37e4b commit 010753d

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
@@ -1014,6 +1014,21 @@ describe('MDC-based MatMenu', () => {
10141014
.toBe(false);
10151015
});
10161016

1017+
it('should be able to move focus inside the `open` event', fakeAsync(() => {
1018+
const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
1019+
fixture.detectChanges();
1020+
1021+
fixture.componentInstance.trigger.menuOpened.subscribe(() => {
1022+
(document.querySelectorAll('.mat-mdc-menu-panel [mat-menu-item]')[3] as HTMLElement).focus();
1023+
});
1024+
fixture.componentInstance.trigger.openMenu();
1025+
fixture.detectChanges();
1026+
tick(500);
1027+
1028+
const items = document.querySelectorAll('.mat-mdc-menu-panel [mat-menu-item]');
1029+
expect(document.activeElement).toBe(items[3], 'Expected fourth item to be focused');
1030+
}));
1031+
10171032
describe('lazy rendering', () => {
10181033
it('should be able to render the menu content lazily', fakeAsync(() => {
10191034
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
@@ -957,6 +957,21 @@ describe('MatMenu', () => {
957957
.toBe(false);
958958
});
959959

960+
it('should be able to move focus inside the `open` event', fakeAsync(() => {
961+
const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
962+
fixture.detectChanges();
963+
964+
fixture.componentInstance.trigger.menuOpened.subscribe(() => {
965+
(document.querySelectorAll('.mat-menu-panel [mat-menu-item]')[3] as HTMLElement).focus();
966+
});
967+
fixture.componentInstance.trigger.openMenu();
968+
fixture.detectChanges();
969+
tick(500);
970+
971+
const items = document.querySelectorAll('.mat-menu-panel [mat-menu-item]');
972+
expect(document.activeElement).toBe(items[3], 'Expected fourth item to be focused');
973+
}));
974+
960975
describe('lazy rendering', () => {
961976
it('should be able to render the menu content lazily', fakeAsync(() => {
962977
const fixture = createComponent(SimpleLazyMenu);

0 commit comments

Comments
 (0)