fix(menu): accidentally tapping on sub-menu content that overlaps trigger on touch devices (#14538)

We depend on the `mouseenter` event to switch between sub-menus, both on touch and mouse devices. Since `mouseenter` is emulated on touch devices, it fires much earlier in the event chain which means that the sub-menu can be shown before the user has lifted their finger. This can be an issue if the sub-menu overlaps the trigger in which case a click will be triggered on the content. These changes fix the issue by re-using an earlier fix that blocks interactions with the panel while it's animating.

Note: an alternate approach can be to do something something similar to what we did with the ripples where we block `mouseenter` for a period after the last `touchstart` event. The problem of doing so is that it'll block all `mouseenter` events on touch devices which we depend on to toggle the panel when switching from one sub-menu to another.
This commit is contained in:
Kristiyan Kostadinov
2018-12-18 16:19:44 +01:00
committed by Jeremy Elbourn
parent bfacbb562e
commit f2a06ab71b
+11 -7
View File
@@ -14,6 +14,17 @@ $mat-menu-submenu-indicator-size: 10px !default;
border-radius: $mat-menu-border-radius;
outline: 0;
// Prevent users from interacting with the panel while it's animating. Note that
// people won't be able to click through it, because the overlay pane will catch the click.
// This fixes the following issues:
// * Users accidentally opening sub-menus when the `overlapTrigger` option is enabled.
// * Users accidentally tapping on content inside the sub-menu on touch devices, if the
// sub-menu overlaps the trigger. The issue is due to touch devices emulating the
// `mouseenter` event by dispatching it on tap.
&.ng-animating {
pointer-events: none;
}
@include cdk-high-contrast {
outline: solid 1px;
}
@@ -70,13 +81,6 @@ $mat-menu-submenu-indicator-size: 10px !default;
transform: rotateY(180deg) translateY(-50%);
}
}
// Prevent the user from interacting while the panel is still animating.
// This avoids issues where the user could accidentally open a sub-menu,
// because of the `overlapTrigger` option.
.mat-menu-panel.ng-animating & {
pointer-events: none;
}
}
button.mat-menu-item {