From a6585246af4c165a12e6254c358f8677ce98156a Mon Sep 17 00:00:00 2001
From: Dan Bucholtz
Date: Wed, 18 May 2016 13:11:59 -0500
Subject: [PATCH] feat(modal): add inset modal feature
* feat(inset-modal): add dynamic component loading functionality for inset modal
* style(modal): moved border-radius to a variable, added an additional data binding activity in moved border-radius to a variable, added an additional data binding activity in an e2e test
* refactor(modal): refactor sass and remove some unnecessary stuff
* refactor(modal): migrate to Angular RC import syntax
Closes #5423
---
ionic/components/modal/modal.ios.scss | 12 +++-
ionic/components/modal/modal.md.scss | 2 +-
ionic/components/modal/modal.scss | 55 ++++++++++++----
ionic/components/modal/modal.ts | 77 +++++++++++++++++++---
ionic/components/modal/modal.wp.scss | 2 +-
ionic/components/modal/test/basic/index.ts | 35 +++++++++-
6 files changed, 153 insertions(+), 30 deletions(-)
diff --git a/ionic/components/modal/modal.ios.scss b/ionic/components/modal/modal.ios.scss
index 9bf6a6f6803..68e67f4aa46 100644
--- a/ionic/components/modal/modal.ios.scss
+++ b/ionic/components/modal/modal.ios.scss
@@ -4,8 +4,16 @@
// --------------------------------------------------
$modal-ios-background-color: $background-ios-color !default;
+$modal-ios-border-radius: 5px !default;
-
-ion-page.modal {
+.modal ion-page {
background-color: $modal-ios-background-color;
}
+
+.modal-wrapper {
+ @media only screen and (min-width: 768px) and (min-height: 600px) {
+ overflow: hidden;
+
+ border-radius: $modal-ios-border-radius;
+ }
+}
diff --git a/ionic/components/modal/modal.md.scss b/ionic/components/modal/modal.md.scss
index 614257d49bb..33fafdf095d 100644
--- a/ionic/components/modal/modal.md.scss
+++ b/ionic/components/modal/modal.md.scss
@@ -6,6 +6,6 @@
$modal-md-background-color: $background-md-color !default;
-ion-page.modal {
+.modal ion-page {
background-color: $modal-md-background-color;
}
diff --git a/ionic/components/modal/modal.scss b/ionic/components/modal/modal.scss
index 9784b3af22a..1a598f9fe0c 100644
--- a/ionic/components/modal/modal.scss
+++ b/ionic/components/modal/modal.scss
@@ -3,27 +3,54 @@
// Modals
// --------------------------------------------------
-ion-page.modal {
- z-index: $z-index-overlay;
+$modal-inset-min-width: 768px !default;
+$modal-inset-min-height-small: 600px !default;
+$modal-inset-min-height-large: 768px !default;
+$modal-inset-width: 600px !default;
+$modal-inset-height-small: 500px !default;
+$modal-inset-height-large: 600px !default;
- // hidden by default to prevent flickers, the animation will show it
- transform: translate3d(0, 100%, 0);
+.modal {
+ position: absolute;
+ top: 0;
+ left: 0;
- @media only screen and (min-width: 768px) and (min-height: 600px){
+ display: block;
+
+ width: 100%;
+ height: 100%;
+
+ .backdrop {
+ @media not all and (min-width: $modal-inset-min-width) and (min-height: $modal-inset-min-height-small) {
+ display: none;
+ }
+ }
+}
+
+.modal-wrapper {
+ z-index: 10;
+
+ height: 100%;
+
+ @media only screen and (min-width: $modal-inset-min-width) and (min-height: $modal-inset-min-height-small) {
position: absolute;
- top: calc(50% - 250px);
- left: calc(50% - 300px);
+ top: calc(50% - (#{$modal-inset-height-small}/2));
+ left: calc(50% - (#{$modal-inset-width}/2));
- width: 600px;
- height: 500px;
+ width: $modal-inset-width;
+ height: $modal-inset-height-small;
}
- @media only screen and (min-width: 768px) and (min-height: 768px){
+ @media only screen and (min-width: $modal-inset-min-width) and (min-height: $modal-inset-min-height-large) {
position: absolute;
- top: calc(50% - 300px);
- left: calc(50% - 300px);
+ top: calc(50% - (#{$modal-inset-height-large}/2));
+ left: calc(50% - (#{$modal-inset-width}/2));
- width: 600px;
- height: 600px;
+ width: $modal-inset-width;
+ height: $modal-inset-height-large;
}
}
+
+.show-page ion-page {
+ display: flex;
+}
diff --git a/ionic/components/modal/modal.ts b/ionic/components/modal/modal.ts
index 6d6a98f1e7c..69ec70f6567 100644
--- a/ionic/components/modal/modal.ts
+++ b/ionic/components/modal/modal.ts
@@ -1,3 +1,6 @@
+import {Component, DynamicComponentLoader, ViewChild, ViewContainerRef} from '@angular/core';
+
+import {NavParams} from '../nav/nav-params';
import {ViewController} from '../nav/view-controller';
import {Animation} from '../../animations/animation';
import {Transition, TransitionOptions} from '../../transitions/transition';
@@ -103,8 +106,9 @@ import {Transition, TransitionOptions} from '../../transitions/transition';
*/
export class Modal extends ViewController {
- constructor(componentType, data = {}) {
- super(componentType, data);
+ constructor(componentType, data: any = {}) {
+ data.componentToPresent = componentType;
+ super(ModalComponent, data);
this.viewType = 'modal';
this.isOverlay = true;
}
@@ -127,6 +131,30 @@ export class Modal extends ViewController {
}
+@Component({
+ selector: 'ion-modal',
+ template: `
+
+
+ `
+})
+class ModalComponent {
+
+ @ViewChild('wrapper', {read: ViewContainerRef}) wrapper: ViewContainerRef;
+
+ constructor(private _loader: DynamicComponentLoader, private _navParams: NavParams, private _viewCtrl: ViewController) {
+ }
+
+ ngAfterViewInit() {
+ let component = this._navParams.data.componentToPresent;
+ this._loader.loadNextToLocation(component, this.wrapper).then(componentInstance => {
+ this._viewCtrl.setInstance(componentInstance.instance);
+ // TODO - validate what life cycle events aren't call and possibly call them here if needed
+ });
+ }
+}
/**
* Animations for modals
@@ -134,12 +162,19 @@ export class Modal extends ViewController {
class ModalSlideIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(opts);
+
+ let ele = enteringView.pageRef().nativeElement;
+ let backdrop = new Animation(ele.querySelector('.backdrop'));
+ backdrop.fromTo('opacity', 0.01, 0.4);
+ let wrapper = new Animation(ele.querySelector('.modal-wrapper'));
+ wrapper.fromTo('translateY', '100%', '0%');
this
.element(enteringView.pageRef())
.easing('cubic-bezier(0.36,0.66,0.04,1)')
.duration(400)
- .fromTo('translateY', '100%', '0%')
- .before.addClass('show-page');
+ .before.addClass('show-page')
+ .add(backdrop)
+ .add(wrapper);
if (enteringView.hasNavbar()) {
// entering page has a navbar
@@ -155,11 +190,19 @@ Transition.register('modal-slide-in', ModalSlideIn);
class ModalSlideOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(opts);
+
+ let ele = leavingView.pageRef().nativeElement;
+ let backdrop = new Animation(ele.querySelector('.backdrop'));
+ backdrop.fromTo('opacity', 0.4, 0.0);
+ let wrapper = new Animation(ele.querySelector('.modal-wrapper'));
+ wrapper.fromTo('translateY', '0%', '100%');
+
this
.element(leavingView.pageRef())
.easing('ease-out')
.duration(250)
- .fromTo('translateY', '0%', '100%');
+ .add(backdrop)
+ .add(wrapper);
}
}
Transition.register('modal-slide-out', ModalSlideOut);
@@ -168,13 +211,21 @@ Transition.register('modal-slide-out', ModalSlideOut);
class ModalMDSlideIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(opts);
+
+ let ele = enteringView.pageRef().nativeElement;
+ let backdrop = new Animation(ele.querySelector('.backdrop'));
+ backdrop.fromTo('opacity', 0.01, 0.4);
+ let wrapper = new Animation(ele.querySelector('.modal-wrapper'));
+ wrapper.fromTo('translateY', '40px', '0px');
+
this
.element(enteringView.pageRef())
.easing('cubic-bezier(0.36,0.66,0.04,1)')
.duration(280)
- .fromTo('translateY', '40px', '0px')
.fadeIn()
- .before.addClass('show-page');
+ .before.addClass('show-page')
+ .add(backdrop)
+ .add(wrapper);
if (enteringView.hasNavbar()) {
// entering page has a navbar
@@ -190,12 +241,20 @@ Transition.register('modal-md-slide-in', ModalMDSlideIn);
class ModalMDSlideOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(opts);
+
+ let ele = leavingView.pageRef().nativeElement;
+ let backdrop = new Animation(ele.querySelector('.backdrop'));
+ backdrop.fromTo('opacity', 0.4, 0.0);
+ let wrapper = new Animation(ele.querySelector('.modal-wrapper'));
+ wrapper.fromTo('translateY', '0px', '40px');
+
this
.element(leavingView.pageRef())
.duration(200)
.easing('cubic-bezier(0.47,0,0.745,0.715)')
- .fromTo('translateY', '0px', '40px')
- .fadeOut();
+ .fadeOut()
+ .add(wrapper)
+ .add(backdrop);
}
}
Transition.register('modal-md-slide-out', ModalMDSlideOut);
diff --git a/ionic/components/modal/modal.wp.scss b/ionic/components/modal/modal.wp.scss
index 8efb3cb9f2c..11f8daa08c0 100644
--- a/ionic/components/modal/modal.wp.scss
+++ b/ionic/components/modal/modal.wp.scss
@@ -6,6 +6,6 @@
$modal-wp-background-color: $background-wp-color !default;
-ion-page.modal {
+.modal ion-page {
background-color: $modal-wp-background-color;
}
diff --git a/ionic/components/modal/test/basic/index.ts b/ionic/components/modal/test/basic/index.ts
index 16703a992be..eeeaca1f565 100644
--- a/ionic/components/modal/test/basic/index.ts
+++ b/ionic/components/modal/test/basic/index.ts
@@ -1,6 +1,5 @@
import {App, Page, Config, Platform} from '../../../../../ionic';
-import {Modal, ActionSheet, NavController, NavParams, Transition, TransitionOptions, ViewController} from '../../../../../ionic';;
-
+import {Modal, ActionSheet, NavController, NavParams, Transition, TransitionOptions, ViewController} from '../../../../../ionic';
@Page({
templateUrl: 'main.html'
@@ -105,6 +104,22 @@ class ModalPassData {
submit() {
this.viewCtrl.dismiss(this.data);
}
+
+ onPageWillEnter(){
+ console.log("ModalPassData onPagewillEnter fired");
+ }
+
+ onPageDidEnter(){
+ console.log("ModalPassData onPageDidEnter fired");
+ }
+
+ onPageWillLeave(){
+ console.log("ModalPassData onPageWillLeave fired");
+ }
+
+ onPageDidLeave(){
+ console.log("ModalPassData onPageDidLeave fired");
+ }
}
@@ -242,11 +257,25 @@ class ContactUs {
+
+
+ Item Number: {{item.value}}
+
+
`
})
class ModalFirstPage {
- constructor(private nav: NavController) {}
+
+ private items:any[];
+ constructor(private nav: NavController) {
+ this.items = [];
+ for ( let i = 0; i < 50; i++ ){
+ this.items.push({
+ value: (i + 1)
+ });
+ }
+ }
push() {
let page = ModalSecondPage;