fix(backdrop): device support

This commit is contained in:
Manu Mtz.-Almeida
2018-02-20 15:00:52 +01:00
parent 9fded75502
commit b05eaeb85b
51 changed files with 221 additions and 271 deletions

View File

@ -342,7 +342,9 @@ declare global {
} }
namespace JSXElements { namespace JSXElements {
export interface IonBackdropAttributes extends HTMLAttributes { export interface IonBackdropAttributes extends HTMLAttributes {
mode?: 'ios' | 'md'; stopPropagation?: boolean;
tappable?: boolean;
visible?: boolean;
} }
} }
} }

View File

@ -13,6 +13,8 @@ ion-action-sheet {
width: $action-sheet-width; width: $action-sheet-width;
height: $action-sheet-width; height: $action-sheet-width;
touch-action: none;
font-smoothing: antialiased; font-smoothing: antialiased;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
} }

View File

@ -195,11 +195,10 @@ export class ActionSheet {
this.dismiss(); this.dismiss();
} }
protected backdropClick() { @Listen('ionBackdropTap')
if (this.enableBackdropDismiss) { protected onBackdropTap() {
this.dismiss(); this.dismiss();
} }
}
protected buttonClick(button: ActionSheetButton) { protected buttonClick(button: ActionSheetButton) {
let shouldDismiss = true; let shouldDismiss = true;
@ -238,9 +237,7 @@ export class ActionSheet {
const buttons = allButtons.filter(b => b.role !== 'cancel'); const buttons = allButtons.filter(b => b.role !== 'cancel');
return [ return [
<ion-backdrop <ion-backdrop tappable={this.enableBackdropDismiss}/>,
onClick={this.backdropClick.bind(this)}
class='action-sheet-backdrop'></ion-backdrop>,
<div class='action-sheet-wrapper' role='dialog'> <div class='action-sheet-wrapper' role='dialog'>
<div class='action-sheet-container'> <div class='action-sheet-container'>
<div class='action-sheet-group'> <div class='action-sheet-group'>

View File

@ -7,7 +7,7 @@ export default function iosEnterAnimation(Animation: Animation, baseEl: HTMLElem
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.action-sheet-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.action-sheet-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.action-sheet-wrapper'));

View File

@ -7,7 +7,7 @@ export default function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElem
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.action-sheet-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.action-sheet-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.action-sheet-wrapper'));

View File

@ -8,7 +8,7 @@ export default function mdEnterAnimation(Animation: Animation, baseEl: HTMLEleme
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.action-sheet-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.action-sheet-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.action-sheet-wrapper'));

View File

@ -7,7 +7,7 @@ export default function mdLeaveAnimation(Animation: Animation, baseEl: HTMLEleme
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.action-sheet-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.action-sheet-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.action-sheet-wrapper'));

View File

@ -15,6 +15,8 @@ ion-alert {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
touch-action: none;
contain: strict; contain: strict;
font-smoothing: antialiased; font-smoothing: antialiased;

View File

@ -1,4 +1,4 @@
import { Component, CssClassMap, Element, Event, EventEmitter, Method, Prop } from '@stencil/core'; import { Component, CssClassMap, Element, Event, EventEmitter, Method, Prop, Listen } from '@stencil/core';
import { Animation, AnimationBuilder, AnimationController, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index'; import { Animation, AnimationBuilder, AnimationController, Config, DomController, OverlayDismissEvent, OverlayDismissEventDetail } from '../../index';
import { domControllerAsync, playAnimationAsync } from '../../utils/helpers'; import { domControllerAsync, playAnimationAsync } from '../../utils/helpers';
@ -204,11 +204,10 @@ export class Alert {
this.ionAlertDidUnload.emit(); this.ionAlertDidUnload.emit();
} }
protected backdropClick() { @Listen('ionBackdropTap')
if (this.enableBackdropDismiss) { protected onBackdropTap() {
this.dismiss(null, BACKDROP); this.dismiss(null, BACKDROP);
} }
}
rbClick(inputIndex: number) { rbClick(inputIndex: number) {
this.inputs = this.inputs.map((input, index) => { this.inputs = this.inputs.map((input, index) => {
@ -419,9 +418,7 @@ export class Alert {
this.inputType = inputTypes.length > 0 ? inputTypes[0] : null; this.inputType = inputTypes.length > 0 ? inputTypes[0] : null;
return [ return [
<ion-backdrop <ion-backdrop tappable={this.enableBackdropDismiss}/>,
onClick={this.backdropClick.bind(this)}
class='alert-backdrop'></ion-backdrop>,
<div class='alert-wrapper'> <div class='alert-wrapper'>
<div class='alert-head'> <div class='alert-head'>
{this.title {this.title

View File

@ -7,7 +7,7 @@ export default function iosEnterAnimation(Animation: Animation, baseEl: HTMLElem
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.alert-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper'));

View File

@ -7,7 +7,7 @@ export default function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElem
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.alert-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper'));

View File

@ -7,7 +7,7 @@ export default function mdEnterAnimation(Animation: Animation, baseEl: HTMLEleme
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.alert-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper'));

View File

@ -7,7 +7,7 @@ export default function mdLeaveAnimation(Animation: Animation, baseEl: HTMLEleme
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.alert-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper'));

View File

@ -13,12 +13,19 @@ ion-backdrop {
width: 100%; width: 100%;
height: 100%; height: 100%;
cursor: pointer;
opacity: .01; opacity: .01;
transform: translateZ(0); transform: translateZ(0);
contain: strict; touch-action: none;
}
ion-backdrop.backdrop-no-tappable { contain: strict;
&.backdrop-hide {
background: transparent;
}
&.backdrop-no-tappable {
cursor: auto; cursor: auto;
}
} }

View File

@ -1,4 +1,5 @@
import { Component, Prop } from '@stencil/core'; import { Component, Listen, EventEmitter, Event, Prop } from '@stencil/core';
import { now } from '../../utils/helpers';
@Component({ @Component({
tag: 'ion-backdrop', tag: 'ion-backdrop',
@ -11,10 +12,44 @@ import { Component, Prop } from '@stencil/core';
} }
}) })
export class Backdrop { export class Backdrop {
/**
* The mode determines which platform styles to use.
* Possible values are: `"ios"` or `"md"`.
*/
@Prop() mode: 'ios' | 'md';
private lastClick = -10000;
@Prop() visible = true;
@Prop() tappable = true;
@Prop() stopPropagation = true;
@Event() ionBackdropTap: EventEmitter;
@Listen('touchstart', {passive: false, capture: true})
protected onTouchStart(ev: TouchEvent) {
this.lastClick = now(ev);
this.emitTap(ev);
}
@Listen('mousedown', {passive: false, capture: true})
protected onMouseDown(ev: TouchEvent) {
if(this.lastClick < now(ev) - 2500) {
this.emitTap(ev);
}
}
private emitTap(ev: Event) {
if(this.stopPropagation) {
ev.preventDefault();
ev.stopPropagation();
}
if (this.tappable) {
this.ionBackdropTap.emit();
}
}
hostData() {
return {
class: {
'backdrop-hide': !this.visible,
'backdrop-no-tappable': !this.tappable,
}
};
}
} }

View File

@ -12,22 +12,41 @@ Backdrops are full screen components that overlay other components. They are use
## Properties ## Properties
#### mode #### stopPropagation
boolean
#### tappable
The mode determines which platform styles to use. boolean
Possible values are: `"ios"` or `"md"`.
#### visible
boolean
## Attributes ## Attributes
#### mode #### stop-propagation
boolean
#### tappable
The mode determines which platform styles to use. boolean
Possible values are: `"ios"` or `"md"`.
#### visible
boolean
## Events
#### ionBackdropTap

View File

@ -8,7 +8,7 @@ export default function iosEnterAnimation(Animation: Animation, baseEl: HTMLElem
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.loading-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper'));

View File

@ -8,7 +8,7 @@ export default function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElem
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.loading-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper'));

View File

@ -7,7 +7,7 @@ export default function mdEnterAnimation(Animation: Animation, baseEl: HTMLEleme
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.loading-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper'));

View File

@ -7,7 +7,7 @@ export default function mdLeaveAnimation(Animation: Animation, baseEl: HTMLEleme
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.loading-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper'));

View File

@ -1,10 +1,6 @@
@import "./loading"; @import "./loading";
@import "./loading.ios.vars"; @import "./loading.ios.vars";
.loading-backdrop-ios {
background-color: $loading-backdrop-ios-color;
}
// iOS Loading Indicator // iOS Loading Indicator
// -------------------------------------------------- // --------------------------------------------------

View File

@ -3,9 +3,6 @@
// iOS Loading Indicator // iOS Loading Indicator
// -------------------------------------------------- // --------------------------------------------------
/// @prop - Color of backdrop
$loading-backdrop-ios-color: $backdrop-ios-color !default;
/// @prop - Font family of the loading wrapper /// @prop - Font family of the loading wrapper
$loading-ios-font-family: $font-family-ios-base !default; $loading-ios-font-family: $font-family-ios-base !default;

View File

@ -1,10 +1,6 @@
@import "./loading"; @import "./loading";
@import "./loading.md.vars"; @import "./loading.md.vars";
.loading-backdrop-ios {
background-color: $loading-backdrop-md-color;
}
// Material Design Loading Indicator // Material Design Loading Indicator
// -------------------------------------------------- // --------------------------------------------------

View File

@ -3,9 +3,6 @@
// Material Design Loading Indicator // Material Design Loading Indicator
// -------------------------------------------------- // --------------------------------------------------
/// @prop - Color of backdrop
$loading-backdrop-md-color: $backdrop-md-color !default;
/// @prop - Font family of the loading wrapper /// @prop - Font family of the loading wrapper
$loading-md-font-family: $font-family-md-base !default; $loading-md-font-family: $font-family-md-base !default;

View File

@ -14,37 +14,15 @@ ion-loading {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
touch-action: none;
contain: strict; contain: strict;
} }
ion-loading ion-gesture {
display: block;
width: 100%;
height: 100%;
visibility: inherit;
}
ion-loading-controller { ion-loading-controller {
display: none; display: none;
} }
.loading-backdrop {
@include position(0, null, null, 0);
position: absolute;
z-index: $z-index-backdrop;
display: block;
width: 100%;
height: 100%;
opacity: .01;
transform: translateZ(0);
}
.loading-wrapper { .loading-wrapper {
z-index: $z-index-overlay-wrapper; z-index: $z-index-overlay-wrapper;
display: flex; display: flex;

View File

@ -151,6 +151,11 @@ export class Loading {
this.dismiss(); this.dismiss();
} }
@Listen('ionBackdropTap')
protected onBackdropTap() {
this.dismiss();
}
/** /**
* Present the loading overlay after it has been created. * Present the loading overlay after it has been created.
*/ */
@ -223,12 +228,6 @@ export class Loading {
}); });
} }
protected backdropClick() {
if (this.enableBackdropDismiss) {
this.dismiss();
}
}
hostData() { hostData() {
const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'loading-translucent') : {}; const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'loading-translucent') : {};
@ -241,8 +240,6 @@ export class Loading {
} }
render() { render() {
const themedClasses = createThemedClasses(this.mode, this.color, 'loading-backdrop');
if (this.cssClass) { if (this.cssClass) {
this.cssClass.split(' ').forEach(cssClass => { this.cssClass.split(' ').forEach(cssClass => {
if (cssClass.trim() !== '') this.el.classList.add(cssClass); if (cssClass.trim() !== '') this.el.classList.add(cssClass);
@ -268,12 +265,7 @@ export class Loading {
} }
return [ return [
<ion-backdrop <ion-backdrop visible={this.showBackdrop} tappable={false} />,
onClick={this.backdropClick.bind(this)}
class={{
...themedClasses,
'hide-backdrop': !this.showBackdrop
}}></ion-backdrop>,
<div class='loading-wrapper' role='dialog'> <div class='loading-wrapper' role='dialog'>
{loadingInner} {loadingInner}
</div> </div>

View File

@ -447,7 +447,13 @@ export class Menu {
<div class='menu-inner page-inner' ref={el => this.menuInnerEl = el}> <div class='menu-inner page-inner' ref={el => this.menuInnerEl = el}>
<slot></slot> <slot></slot>
</div>, </div>,
<ion-backdrop class='menu-backdrop' ref={el => this.backdropEl = el}></ion-backdrop> ,
<ion-backdrop
ref={el => this.backdropEl = el}
class='menu-backdrop'
tappable={false}
stopPropagation={false}/>,
<ion-gesture {...{ <ion-gesture {...{
'canStart': this.canStart.bind(this), 'canStart': this.canStart.bind(this),
'onWillStart': this.onWillStart.bind(this), 'onWillStart': this.onWillStart.bind(this),
@ -465,7 +471,7 @@ export class Menu {
'attachTo': 'body', 'attachTo': 'body',
'disableScroll': true, 'disableScroll': true,
'block': this.gestureBlocker 'block': this.gestureBlocker
}}></ion-gesture> }}/>
]); ]);
} }
} }

View File

@ -6,6 +6,15 @@
<title>Menu - Basic</title> <title>Menu - Basic</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<script src="/dist/ionic.js"></script> <script src="/dist/ionic.js"></script>
<style>
.f {
width: 200px;
height: 200px;
background: blue;
margin: 20px auto;
}
</style>
</head> </head>
<body> <body>
@ -75,6 +84,14 @@
<ion-button onclick="setEnabled()">Set Swipe Enabled False</ion-button> <ion-button onclick="setEnabled()">Set Swipe Enabled False</ion-button>
</p> </p>
<div class="f"></div>
<div class="f"></div>
<div class="f"></div>
<div class="f"></div>
<div class="f"></div>
<div class="f"></div>
</ion-content> </ion-content>
</ion-page> </ion-page>

View File

@ -8,7 +8,7 @@ export default function iosEnterAnimation(Animation: Animation, baseEl: HTMLElem
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.modal-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));

View File

@ -8,7 +8,7 @@ export default function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElem
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.modal-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
const wrapperEl = baseEl.querySelector('.modal-wrapper'); const wrapperEl = baseEl.querySelector('.modal-wrapper');

View File

@ -7,7 +7,7 @@ export default function mdEnterAnimation(Animation: Animation, baseEl: HTMLEleme
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.modal-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.modal-wrapper'));

View File

@ -7,7 +7,7 @@ export default function mdLeaveAnimation(Animation: Animation, baseEl: HTMLEleme
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.modal-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
const wrapperEl = baseEl.querySelector('.modal-wrapper'); const wrapperEl = baseEl.querySelector('.modal-wrapper');

View File

@ -1,10 +1,6 @@
@import "./modal"; @import "./modal";
@import "./modal.ios.vars"; @import "./modal.ios.vars";
.modal-backdrop-ios {
background-color: $modal-backdrop-ios-color;
}
// iOS Modals // iOS Modals
// -------------------------------------------------- // --------------------------------------------------

View File

@ -3,9 +3,6 @@
// iOS Modals // iOS Modals
// -------------------------------------------------- // --------------------------------------------------
/// @prop - Color of backdrop
$modal-backdrop-ios-color: $backdrop-ios-color !default;
/// @prop - Background color for the modal /// @prop - Background color for the modal
$modal-ios-background-color: $background-ios-color !default; $modal-ios-background-color: $background-ios-color !default;

View File

@ -1,9 +1,6 @@
@import "./modal"; @import "./modal";
@import "./modal.md.vars"; @import "./modal.md.vars";
.modal-backdrop-md {
background-color: $modal-backdrop-md-color;
}
// Material Design Modals // Material Design Modals
// -------------------------------------------------- // --------------------------------------------------

View File

@ -3,9 +3,6 @@
// Material Design Modals // Material Design Modals
// -------------------------------------------------- // --------------------------------------------------
/// @prop - Color of backdrop
$modal-backdrop-md-color: $backdrop-md-color !default;
/// @prop - Background color for the modal /// @prop - Background color for the modal
$modal-md-background-color: $background-md-color !default; $modal-md-background-color: $background-md-color !default;

View File

@ -20,33 +20,13 @@ ion-modal-controller {
display: none; display: none;
} }
.modal-backdrop {
@include position(0, null, null, 0);
position: absolute; @media not all and (min-width: $modal-inset-min-width) and (min-height: $modal-inset-min-height-small) {
ion-modal ion-backdrop {
z-index: $z-index-backdrop; display: none;
display: block;
width: 100%;
height: 100%;
opacity: .01;
transform: translateZ(0);
@media not all and (min-width: $modal-inset-min-width) and (min-height: $modal-inset-min-height-small) {
visibility: hidden;
} }
} }
.modal-backdrop.backdrop-no-tappable {
cursor: auto;
}
.modal-backdrop.hide-backdrop {
visibility: hidden;
}
.modal-wrapper { .modal-wrapper {
z-index: 10; z-index: 10;

View File

@ -120,6 +120,30 @@ export class Modal {
*/ */
@Event() ionModalDidUnload: EventEmitter<ModalEventDetail>; @Event() ionModalDidUnload: EventEmitter<ModalEventDetail>;
componentDidLoad() {
this.ionModalDidLoad.emit();
}
componentDidUnload() {
this.ionModalDidUnload.emit();
}
@Listen('ionDismiss')
protected onDismiss(ev: UIEvent) {
ev.stopPropagation();
ev.preventDefault();
this.dismiss();
}
@Listen('ionBackdropTap')
protected onBackdropTap() {
// const opts: NavOptions = {
// minClickBlockDuration: 400
// };
this.dismiss();
}
/** /**
* Present the modal overlay after it has been created. * Present the modal overlay after it has been created.
*/ */
@ -212,42 +236,11 @@ export class Modal {
return this.el.querySelector(`.${USER_COMPONENT_MODAL_CONTAINER_CLASS}`); return this.el.querySelector(`.${USER_COMPONENT_MODAL_CONTAINER_CLASS}`);
} }
@Listen('ionDismiss')
protected onDismiss(ev: UIEvent) {
ev.stopPropagation();
ev.preventDefault();
this.dismiss();
}
componentDidLoad() {
this.ionModalDidLoad.emit();
}
componentDidUnload() {
this.ionModalDidUnload.emit();
}
protected backdropClick() {
if (this.enableBackdropDismiss) {
// const opts: NavOptions = {
// minClickBlockDuration: 400
// };
this.dismiss();
}
}
render() { render() {
const backdropClasses = createThemedClasses(this.mode, this.color, 'modal-backdrop');
const dialogClasses = createThemedClasses(this.mode, this.color, 'modal-wrapper'); const dialogClasses = createThemedClasses(this.mode, this.color, 'modal-wrapper');
return [ return [
<ion-backdrop <ion-backdrop visible={this.showBackdrop} tappable={this.enableBackdropDismiss}/>,
onClick={this.backdropClick.bind(this)}
class={{
...backdropClasses,
'hide-backdrop': !this.showBackdrop
}}></ion-backdrop>,
<div role='dialog' class={dialogClasses}></div> <div role='dialog' class={dialogClasses}></div>
]; ];
} }

View File

@ -343,8 +343,7 @@ export class Nav implements PublicNav, NavOutlet {
type='pan' type='pan'
direction='x' direction='x'
threshold={10} threshold={10}
attachTo='body' attachTo='body'/>);
></ion-gesture>);
} }
if (this.mode === 'ios') { if (this.mode === 'ios') {
dom.push(<div class='nav-decor'/>); dom.push(<div class='nav-decor'/>);

View File

@ -8,7 +8,7 @@ export default function iosEnterAnimation(Animation: Animation, baseEl: HTMLElem
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.picker-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.picker-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.picker-wrapper'));

View File

@ -8,7 +8,7 @@ export default function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElem
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.picker-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.picker-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.picker-wrapper'));

View File

@ -218,6 +218,16 @@ export class Picker {
this.dismiss(); this.dismiss();
} }
@Listen('ionBackdropTap')
protected onBackdropTap() {
const cancelBtn = this.buttons.find(b => b.role === 'cancel');
if (cancelBtn) {
this.buttonClick(cancelBtn);
} else {
this.dismiss();
}
}
buttonClick(button: PickerButton) { buttonClick(button: PickerButton) {
// if (this.disabled) { // if (this.disabled) {
// return; // return;
@ -273,18 +283,6 @@ export class Picker {
return this.columns; return this.columns;
} }
protected backdropClick() {
// TODO !this.disabled
if (this.enableBackdropDismiss) {
const cancelBtn = this.buttons.find(b => b.role === 'cancel');
if (cancelBtn) {
this.buttonClick(cancelBtn);
} else {
this.dismiss();
}
}
}
render() { render() {
// TODO: cssClass // TODO: cssClass
@ -332,12 +330,7 @@ export class Picker {
// }); // });
return [ return [
<ion-backdrop <ion-backdrop visible={this.showBackdrop} tappable={this.enableBackdropDismiss}/>,
onClick={this.backdropClick.bind(this)}
class={{
'picker-backdrop': true,
'hide-backdrop': !this.showBackdrop
}}></ion-backdrop>,
<div class='picker-wrapper' role='dialog'> <div class='picker-wrapper' role='dialog'>
<div class='picker-toolbar'> <div class='picker-toolbar'>
{buttons.map(b => {buttons.map(b =>

View File

@ -116,7 +116,7 @@ export default function iosEnterAnimation(Animation: Animation, baseEl: HTMLElem
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.popover-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
backdropAnimation.fromTo('opacity', 0.01, 0.08); backdropAnimation.fromTo('opacity', 0.01, 0.08);
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();

View File

@ -7,7 +7,7 @@ export default function iosLeaveAnimation(Animation: Animation, baseEl: HTMLElem
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.popover-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.popover-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.popover-wrapper'));

View File

@ -70,7 +70,7 @@ export default function mdEnterAnimation(Animation: Animation, baseEl: HTMLEleme
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.popover-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
backdropAnimation.fromTo('opacity', 0.01, 0.08); backdropAnimation.fromTo('opacity', 0.01, 0.08);
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();

View File

@ -7,7 +7,7 @@ export default function mdLeaveAnimation(Animation: Animation, baseEl: HTMLEleme
const baseAnimation = new Animation(); const baseAnimation = new Animation();
const backdropAnimation = new Animation(); const backdropAnimation = new Animation();
backdropAnimation.addElement(baseEl.querySelector('.popover-backdrop')); backdropAnimation.addElement(baseEl.querySelector('ion-backdrop'));
const wrapperAnimation = new Animation(); const wrapperAnimation = new Animation();
wrapperAnimation.addElement(baseEl.querySelector('.popover-wrapper')); wrapperAnimation.addElement(baseEl.querySelector('.popover-wrapper'));

View File

@ -1,10 +1,6 @@
@import "./popover"; @import "./popover";
@import "./popover.ios.vars"; @import "./popover.ios.vars";
.popover-backdrop-ios {
background-color: $popover-backdrop-ios-color;
}
// iOS Popover // iOS Popover
// -------------------------------------------------- // --------------------------------------------------

View File

@ -1,10 +1,6 @@
@import "./popover"; @import "./popover";
@import "./popover.md.vars"; @import "./popover.md.vars";
.popover-backdrop-md {
background-color: $popover-backdrop-md-color;
}
// Material Design Popover // Material Design Popover
// -------------------------------------------------- // --------------------------------------------------

View File

@ -1,8 +1,5 @@
@import "../../themes/ionic.globals.md"; @import "../../themes/ionic.globals.md";
/// @prop - Color of backdrop
$popover-backdrop-md-color: $backdrop-md-color !default;
// Material Design Popover // Material Design Popover
// -------------------------------------------------- // --------------------------------------------------

View File

@ -45,26 +45,3 @@ ion-popover {
ion-popover-controller { ion-popover-controller {
display: none; display: none;
} }
// Popover Backdrop
// --------------------------------------------------
.popover-backdrop {
@include position(0, null, null, 0);
position: absolute;
z-index: $z-index-backdrop;
display: block;
width: 100%;
height: 100%;
opacity: .01;
transform: translateZ(0);
}
.popover-backdrop.backdrop-no-tappable {
cursor: auto;
}

View File

@ -128,6 +128,34 @@ export class Popover {
*/ */
@Event() ionPopoverDidUnload: EventEmitter<PopoverEventDetail>; @Event() ionPopoverDidUnload: EventEmitter<PopoverEventDetail>;
componentDidLoad() {
this.ionPopoverDidLoad.emit();
}
componentDidEnter() {
this.ionPopoverDidPresent.emit();
}
componentDidUnload() {
this.ionPopoverDidUnload.emit();
}
@Listen('ionDismiss')
protected onDismiss(ev: UIEvent) {
ev.stopPropagation();
ev.preventDefault();
this.dismiss();
}
@Listen('ionBackdropTap')
protected onBackdropTap() {
// const opts: NavOptions = {
// minClickBlockDuration: 400
// };
this.dismiss();
}
/** /**
* Present the popover overlay after it has been created. * Present the popover overlay after it has been created.
*/ */
@ -211,57 +239,21 @@ export class Popover {
}); });
} }
componentDidLoad() {
this.ionPopoverDidLoad.emit();
}
componentDidEnter() {
this.ionPopoverDidPresent.emit();
}
componentDidUnload() {
this.ionPopoverDidUnload.emit();
}
@Listen('ionDismiss')
protected onDismiss(ev: UIEvent) {
ev.stopPropagation();
ev.preventDefault();
this.dismiss();
}
protected backdropClick() {
if (this.enableBackdropDismiss) {
// const opts: NavOptions = {
// minClickBlockDuration: 400
// };
this.dismiss();
}
}
hostData() { hostData() {
const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'popover-translucent') : {}; const themedClasses = this.translucent ? createThemedClasses(this.mode, this.color, 'popover-translucent') : {};
const hostClasses = {
...themedClasses
};
return { return {
class: hostClasses class: {
...themedClasses
}
}; };
} }
render() { render() {
const backdropClasses = createThemedClasses(this.mode, this.color, 'popover-backdrop'), const wrapperClasses = createThemedClasses(this.mode, this.color, 'popover-wrapper');
wrapperClasses = createThemedClasses(this.mode, this.color, 'popover-wrapper');
return [ return [
<ion-backdrop <ion-backdrop tappable={this.enableBackdropDismiss}/>,
onClick={this.backdropClick.bind(this)}
class={{
...backdropClasses
}}></ion-backdrop>,
<div class={wrapperClasses}> <div class={wrapperClasses}>
<div class='popover-arrow' /> <div class='popover-arrow' />
<div class='popover-content'> <div class='popover-content'>