From 1a865eaf7bfa2c5180e76123df684dd70d78819c Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Fri, 30 Oct 2015 23:31:23 -0500 Subject: [PATCH] feat(nav): animate nested navs --- ionic/components/nav/nav-controller.ts | 4 +- ionic/components/nav/nav.ts | 51 +++++++---------------- ionic/components/nav/test/nested/index.ts | 48 ++++++++++++++++++--- ionic/transitions/ios-transition.ts | 3 ++ ionic/transitions/md-transition.ts | 8 ++-- 5 files changed, 67 insertions(+), 47 deletions(-) diff --git a/ionic/components/nav/nav-controller.ts b/ionic/components/nav/nav-controller.ts index 681c418bdb..c8a1b27249 100644 --- a/ionic/components/nav/nav-controller.ts +++ b/ionic/components/nav/nav-controller.ts @@ -184,7 +184,7 @@ export class NavController extends Ion { if (opts.preCleanup !== false) { raf(() => { this._cleanup(enteringView); - }); + }); } if (this.router) { @@ -286,7 +286,7 @@ export class NavController extends Ion { let leavingView = this._views[this._views.length - 1]; let enteringView = view; - if(this.router) { + if (this.router) { this.router.stateChange('pop', enteringView); } diff --git a/ionic/components/nav/nav.ts b/ionic/components/nav/nav.ts index d1106fc800..afa7700be0 100644 --- a/ionic/components/nav/nav.ts +++ b/ionic/components/nav/nav.ts @@ -4,6 +4,7 @@ import {IonicApp} from '../app/app'; import {Config} from '../../config/config'; import {ConfigComponent} from '../../config/decorators'; import {NavController} from './nav-controller'; +import {ViewController} from './view-controller'; /** * _For a quick walkthrough of navigation in Ionic, check out the @@ -59,25 +60,23 @@ import {NavController} from './nav-controller'; * <ion-nav> * | * | - * Pane 3 +--------------------+ LoginPage - * Pane 2 +--------------------+ | Has header, animates into pane 1 - * Pane 1 +--------------------+ | | +--------------------+ - * | | Header (Pane 1) |<-----------------| Login | + * Page 3 +--------------------+ LoginPage + * Page 2 +--------------------+ | + * Page 1 +--------------------+ | | +--------------------+ + * | | Header |<-----------------| Login | * +--------------------+ | | +--------------------+ * | | | | | | | Username: | * | | | | | | | Password: | - * | | | Pane 3 is | | | | | + * | | | Page 3 is | | | | | * | | | only content | | | | | * | | | |<-----------------| | * | | | | | | | | * | | | | | | | | * | +------------------|-+ | | | - * | | Footer (Pane 2)--|-|-+ | | + * | | Footer |-|-+ | | * | +------------------|-+ | | * +--------------------+ +--------------------+ - * <ion-pane> <ion-view> * - * Pane 1 Pane 2 Pane 3 * +--------------------+ +--------------------+ +--------------------+ * | Header | | Content | | Content | * +--------------------+ | | | | @@ -96,31 +95,6 @@ import {NavController} from './nav-controller'; * * * - * ### Panes - * - * NOTE: You don't have to do anything with panes because Ionic takes care of - * animated transitions for you. This is an explanation of how Nav works to - * accompany the diagram above. - * - * When you push a new page onto the navigation stack using [NavController.push()](../NavController/#push) - * or the [NavPush directive](../NavPush/), Nav animates the new page into the - * appropriate pane. - * - * Panes are the containers Nav creates to animate views into. They do not have - * any content of their own, as they are just a structural reference for where - * the various parts of a page (header, footer, content) should animate into. - * - * The easiest scenario is animating between pages with the same structure. If - * you have a page with a header and content, and navigate to another page that - * also has a header and content, Nav can smoothly animate the incoming page - * into the pane the exiting page is leaving. This allows for things like - * seamless header animations between pages that both have headers. - * - * But suppose you have a page with a header and content and want to navigate to - * a page with no header. Nav creates a new pane with no header that is directly - * behind the current pane. It then animates the exiting page out of the current - * pane and the new page into the new content-only pane. - * */ @ConfigComponent({ selector: 'ion-nav', @@ -136,6 +110,7 @@ export class Nav extends NavController { constructor( @Optional() hostNavCtrl: NavController, + @Optional() viewCtrl: ViewController, app: IonicApp, config: Config, elementRef: ElementRef, @@ -146,11 +121,15 @@ export class Nav extends NavController { renderer: Renderer ) { super(hostNavCtrl, app, config, elementRef, compiler, loader, viewManager, zone, renderer); + + if (viewCtrl) { + // an ion-nav can also act as an ion-page within a parent ion-nav + // this would happen when an ion-nav nests a child ion-nav. + viewCtrl.setContent(this); + viewCtrl.setContentRef(elementRef); + } } - /** - * @private - */ onInit() { super.onInit(); diff --git a/ionic/components/nav/test/nested/index.ts b/ionic/components/nav/test/nested/index.ts index ad14126e51..59de5949d7 100644 --- a/ionic/components/nav/test/nested/index.ts +++ b/ionic/components/nav/test/nested/index.ts @@ -24,7 +24,7 @@ export class Login { } - @Page({ +@Page({ template: ` @@ -67,7 +67,7 @@ export class Account { } logOut() { - this.app.getComponent('root-nav').setRoot(Login); + this.app.getComponent('root-nav').setRoot(Login, null, { animate: true }); } } @@ -75,27 +75,63 @@ export class Account { @Page({ template: ` + + + Account Dashboard - Dashboard +

+

` }) -export class Dashboard {} +export class Dashboard { + constructor(app: IonicApp, nav: NavController) { + this.app = app; + this.nav = nav; + } + goToProfile() { + this.nav.push(Profile); + } + logOut() { + this.app.getComponent('root-nav').setRoot(Login, null, { + animate: true, + direction: 'back' + }); + } +} @Page({ template: ` + + + Account Profile - Profile +

+

` }) -export class Profile {} +export class Profile { + constructor(app: IonicApp, nav: NavController) { + this.app = app; + this.nav = nav; + } + goToDashboard() { + this.nav.push(Dashboard); + } + logOut() { + this.app.getComponent('root-nav').setRoot(Login, null, { + animate: true, + direction: 'back' + }); + } +} @App({ diff --git a/ionic/transitions/ios-transition.ts b/ionic/transitions/ios-transition.ts index b55cb5be2e..7ad3499ca1 100644 --- a/ionic/transitions/ios-transition.ts +++ b/ionic/transitions/ios-transition.ts @@ -106,6 +106,9 @@ class IOSTransition extends Animation { let enteringBackBtnText = new Animation(enteringView.backBtnTextRef()); enteringBackBtnText.fromTo(TRANSLATEX, '100px', '0px'); enteringNavBar.add(enteringBackBtnText); + + } else { + enteringBackButton.before.removeClass(SHOW_BACK_BTN_CSS); } } } diff --git a/ionic/transitions/md-transition.ts b/ionic/transitions/md-transition.ts index 2ead0ff4e3..8bef0c5a4d 100644 --- a/ionic/transitions/md-transition.ts +++ b/ionic/transitions/md-transition.ts @@ -39,11 +39,13 @@ class MDTransition extends Animation { .fadeIn(); } - // entering navbar + let enteringBackButton = new Animation(enteringView.backBtnRef()); + this.add(enteringBackButton); if (enteringHasNavbar && enteringView.enableBack()) { - let enteringBackButton = new Animation(enteringView.backBtnRef()); enteringBackButton.before.addClass(SHOW_BACK_BTN_CSS); - this.add(enteringBackButton); + + } else { + enteringBackButton.before.removeClass(SHOW_BACK_BTN_CSS); } // setup leaving view