fix(menu): overlays can block menu closing

fixes #15880
This commit is contained in:
Manu Mtz.-Almeida
2018-10-08 13:31:27 -05:00
parent e51f1f36f1
commit 11aa241dac
5 changed files with 53 additions and 17 deletions

View File

@ -2,7 +2,8 @@ import { Component, ComponentInterface, Element, Listen, Prop } from '@stencil/c
import { matchBreakpoint } from '../../utils/media'; import { matchBreakpoint } from '../../utils/media';
const SUPPORTS_VARS = !!(window.CSS && window.CSS.supports && window.CSS.supports('--a: 0')); const win = window as any;
const SUPPORTS_VARS = !!(win.CSS && win.CSS.supports && win.CSS.supports('--a: 0'));
const BREAKPOINTS = ['', 'xs', 'sm', 'md', 'lg', 'xl']; const BREAKPOINTS = ['', 'xs', 'sm', 'md', 'lg', 'xl'];
@Component({ @Component({

View File

@ -1,6 +1,19 @@
@import "../menu/menu.ios.vars"; @import "../menu/menu.ios.vars";
@import "../menu/menu.md.vars"; @import "../menu/menu.md.vars";
.menu-content {
@include transform(translate3d(0, 0, 0));
}
.menu-content-open {
cursor: pointer;
touch-action: manipulation;
// the containing element itself should be clickable but
// everything inside of it should not clickable when menu is open
pointer-events: none;
}
.ios .menu-content-reveal { .ios .menu-content-reveal {
box-shadow: $menu-ios-box-shadow-reveal; box-shadow: $menu-ios-box-shadow-reveal;
} }

View File

@ -66,19 +66,6 @@ ion-backdrop {
z-index: -1; z-index: -1;
} }
.menu-content {
@include transform(translate3d(0, 0, 0));
}
.menu-content-open {
cursor: pointer;
touch-action: manipulation;
// the containing element itself should be clickable but
// everything inside of it should not clickable when menu is open
pointer-events: none;
}
@media (max-width: 340px) { @media (max-width: 340px) {
.menu-inner { .menu-inner {

View File

@ -203,7 +203,7 @@ export class Menu implements ComponentInterface, MenuI {
this.updateState(); this.updateState();
} }
@Listen('body:click', { enabled: false, capture: true }) @Listen('click', { enabled: false, capture: true })
onBackdropClick(ev: any) { onBackdropClick(ev: any) {
if (this.lastOnEnd < ev.timeStamp - 100) { if (this.lastOnEnd < ev.timeStamp - 100) {
const shouldClose = (ev.composedPath) const shouldClose = (ev.composedPath)
@ -412,7 +412,7 @@ export class Menu implements ComponentInterface, MenuI {
} }
// add/remove backdrop click listeners // add/remove backdrop click listeners
this.enableListener(this, 'body:click', isOpen); this.enableListener(this, 'click', isOpen);
if (isOpen) { if (isOpen) {
// add css class // add css class

View File

@ -21,6 +21,7 @@
<body> <body>
<ion-app> <ion-app>
<ion-modal-controller></ion-modal-controller>
<ion-menu side="start" class="e2eLeftMenu"> <ion-menu side="start" class="e2eLeftMenu">
<ion-header> <ion-header>
@ -32,7 +33,7 @@
<ion-content> <ion-content>
<ion-list> <ion-list>
<ion-item button onclick="openEnd()">Open end Menu</ion-item> <ion-item button onclick="openEnd()">Open end Menu</ion-item>
<ion-item>Close Menu</ion-item> <ion-item button onclick="createModal()">Open Modal</ion-item>
<ion-item>Close Menu</ion-item> <ion-item>Close Menu</ion-item>
<ion-item>Close Menu</ion-item> <ion-item>Close Menu</ion-item>
<ion-item>Close Menu</ion-item> <ion-item>Close Menu</ion-item>
@ -133,6 +134,40 @@
async function setEnabled() { async function setEnabled() {
(await menu.get('start')).swipeGesture = false; (await menu.get('start')).swipeGesture = false;
} }
async function createModal() {
// initialize controller
const modalController = document.querySelector('ion-modal-controller');
await modalController.componentOnReady();
// create component to open
const element = document.createElement('div');
element.innerHTML = `
<ion-header>
<ion-toolbar>
<ion-title>Super Modal</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<h1>Content of doom</h1>
<div>Here's some more content</div>
<ion-button class="dismiss">Dismiss Modal</ion-button>
</ion-content>
`;
// listen for close event
const button = element.querySelector('ion-button');
button.addEventListener('click', () => {
modalController.dismiss();
});
// present the modal
const modalElement = await modalController.create({
component: element
});
await modalElement.present();
return modalElement;
}
</script> </script>
</body> </body>