Skip to content

Commit f5006d6

Browse files
crisbetoVivian Hu
authored andcommitted
fix(menu): use passive touch listener (#14041)
Fixes a warning from Chrome that the `mat-menu-trigger` is using a blocking `touchstart` listener.
1 parent 9239c04 commit f5006d6

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

src/lib/menu/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ ng_module(
2020
"//src/cdk/keycodes",
2121
"//src/cdk/overlay",
2222
"//src/cdk/portal",
23+
"//src/cdk/platform",
2324
"//src/lib/core",
2425
],
2526
)

src/lib/menu/menu-trigger.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
Self,
3434
ViewContainerRef,
3535
} from '@angular/core';
36+
import {normalizePassiveListenerOptions} from '@angular/cdk/platform';
3637
import {asapScheduler, merge, of as observableOf, Subscription} from 'rxjs';
3738
import {delay, filter, take, takeUntil} from 'rxjs/operators';
3839
import {MatMenu} from './menu-directive';
@@ -60,6 +61,9 @@ export const MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER = {
6061
/** Default top padding of the menu panel. */
6162
export const MENU_PANEL_TOP_PADDING = 8;
6263

64+
/** Options for binding a passive event listener. */
65+
const passiveEventListenerOptions = normalizePassiveListenerOptions({passive: true});
66+
6367
// TODO(andrewseguin): Remove the kebab versions in favor of camelCased attribute selectors
6468

6569
/**
@@ -72,7 +76,6 @@ export const MENU_PANEL_TOP_PADDING = 8;
7276
'aria-haspopup': 'true',
7377
'[attr.aria-expanded]': 'menuOpen || null',
7478
'(mousedown)': '_handleMousedown($event)',
75-
'(touchstart)': '_openedBy = "touch"',
7679
'(keydown)': '_handleKeydown($event)',
7780
'(click)': '_handleClick($event)',
7881
},
@@ -87,6 +90,12 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
8790
private _menuCloseSubscription = Subscription.EMPTY;
8891
private _scrollStrategy: () => ScrollStrategy;
8992

93+
/**
94+
* Handles touch start events on the trigger.
95+
* Needs to be an arrow function so we can easily use addEventListener and removeEventListener.
96+
*/
97+
private _handleTouchStart = () => this._openedBy = 'touch';
98+
9099
// Tracking input type is necessary so it's possible to only auto-focus
91100
// the first item of the list when the menu is opened via the keyboard
92101
_openedBy: 'mouse' | 'touch' | null = null;
@@ -161,6 +170,9 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
161170
// @breaking-change 8.0.0
162171
private _focusMonitor?: FocusMonitor) {
163172

173+
_element.nativeElement.addEventListener('touchstart', this._handleTouchStart,
174+
passiveEventListenerOptions);
175+
164176
if (_menuItemInstance) {
165177
_menuItemInstance._triggersSubmenu = this.triggersSubmenu();
166178
}
@@ -179,6 +191,9 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
179191
this._overlayRef = null;
180192
}
181193

194+
this._element.nativeElement.removeEventListener('touchstart', this._handleTouchStart,
195+
passiveEventListenerOptions);
196+
182197
this._cleanUpSubscriptions();
183198
}
184199

0 commit comments

Comments
 (0)