From 7f665ca459ae6001677928bf65d218d698b1be8a Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Tue, 2 Jun 2015 15:31:18 -0500 Subject: [PATCH] ion-nav-pane --- ionic/components.js.orig | 35 -- ionic/components/app/structure.scss | 11 +- ionic/components/nav-bar/nav-bar.js | 3 +- ionic/components/nav/nav-base.js | 24 +- ionic/components/nav/nav-item.js | 163 ++++++--- ionic/components/nav/nav.js | 544 ++++++++++++++++++++++++++-- ionic/components/view/view.scss | 15 +- 7 files changed, 659 insertions(+), 136 deletions(-) delete mode 100644 ionic/components.js.orig diff --git a/ionic/components.js.orig b/ionic/components.js.orig deleted file mode 100644 index 9f89990024..0000000000 --- a/ionic/components.js.orig +++ /dev/null @@ -1,35 +0,0 @@ -// DON'T reference this file in the source. Only in demos. -export * from 'ionic/components/app/app' -export * from 'ionic/components/action-menu/action-menu' -// export * from 'ionic/components/alert/alert' -export * from 'ionic/components/aside/aside' -export * from 'ionic/components/button/button' -export * from 'ionic/components/checkbox/checkbox' -export * from 'ionic/components/content/content' -export * from 'ionic/components/icon/icon' -export * from 'ionic/components/item/item' -export * from 'ionic/components/form/form' -export * from 'ionic/components/form/input/input' -export * from 'ionic/components/form/label/label' -// export * from 'ionic/components/layout/layout' -export * from 'ionic/components/list/list' -export * from 'ionic/components/modal/modal' -export * from 'ionic/components/nav/nav' -export * from 'ionic/components/nav/nav-controller' -export * from 'ionic/components/nav/nav-item' -export * from 'ionic/components/nav-bar/nav-bar' -export * from 'ionic/components/slides/slides' -export * from 'ionic/components/radio/radio' -// export * from 'ionic/components/search-bar/search-bar' -// export * from 'ionic/components/split-view/split-view' -export * from 'ionic/components/segment/segment' -export * from 'ionic/components/switch/switch' -<<<<<<< HEAD -export * from 'ionic/components/tabs/tabs' -export * from 'ionic/components/tabs/tab' -======= -export * from 'ionic/components/toolbar/toolbar' -export * from 'ionic/components/view/view' -//export * from 'ionic/components/tabs/tabs' -//export * from 'ionic/components/tabs/tab' ->>>>>>> origin/master diff --git a/ionic/components/app/structure.scss b/ionic/components/app/structure.scss index d24e572759..bd554a63f9 100644 --- a/ionic/components/app/structure.scss +++ b/ionic/components/app/structure.scss @@ -53,7 +53,7 @@ ion-tab { } } -ion-nav { +ion-nav-pane { position: absolute; top: 0; right: 0; @@ -67,6 +67,14 @@ ion-nav { flex-direction: column; } +.nav-item { + display: none; + + &.show-view { + display: flex; + } +} + .navbar-container { position: relative; min-height: 4.4rem; @@ -88,7 +96,6 @@ ion-navbar { &.show-navbar { display: flex; } - } ion-toolbar { diff --git a/ionic/components/nav-bar/nav-bar.js b/ionic/components/nav-bar/nav-bar.js index bea1defd39..32af147c9d 100644 --- a/ionic/components/nav-bar/nav-bar.js +++ b/ionic/components/nav-bar/nav-bar.js @@ -107,7 +107,6 @@ export class Navbar { }) export class NavbarTemplate { constructor(navItem: NavItem, protoViewRef: ProtoViewRef) { - console.log('NavbarTemplate', protoViewRef) - navItem.navbarProto(protoViewRef); + navItem.addProtoViewRef('navbar', protoViewRef) } } diff --git a/ionic/components/nav/nav-base.js b/ionic/components/nav/nav-base.js index 797b4419a4..70e8cced85 100644 --- a/ionic/components/nav/nav-base.js +++ b/ionic/components/nav/nav-base.js @@ -15,10 +15,11 @@ const CACHED_STATE = 'cached'; export class NavBase { - constructor(elementRef, loader, injector) { + constructor(elementRef, loader, injector, compiler) { this.elementRef = elementRef; this.loader = loader; this.injector = injector; + this.compile = compiler.compile; this.items = []; this.navCtrl = new NavController(this); this.sbTransition = null; @@ -26,14 +27,9 @@ export class NavBase { this.domElement = elementRef.domElement; } - clear() { - let pops = []; - for(let item of this.items) { - pops.push(this.pop({ - animate: false - })); - } - return Promise.all(pops); + templateAnchor(viewContainerRef, elementRef) { + this.viewContainerRef = viewContainerRef; + this.elementRef = elementRef; } push(Component, params = {}, opts = {}) { @@ -319,6 +315,16 @@ export class NavBase { return false; } + clear() { + let pops = []; + for(let item of this.items) { + pops.push(this.pop({ + animate: false + })); + } + return Promise.all(pops); + } + getActive() { for (let i = 0, ii = this.items.length; i < ii; i++) { if (this.items[i].state === ACTIVE_STATE) { diff --git a/ionic/components/nav/nav-item.js b/ionic/components/nav/nav-item.js index 8bcefe0d94..9fc73f71c2 100644 --- a/ionic/components/nav/nav-item.js +++ b/ionic/components/nav/nav-item.js @@ -3,6 +3,8 @@ import {bind} from 'angular2/di'; import * as util from 'ionic/util'; import {NavController} from './nav-controller'; +import {Nav} from './nav'; +import {NavPane, NavPaneSection} from './nav'; export class NavItem { @@ -12,79 +14,146 @@ export class NavItem { this.Component = Component; this.params = params; this.id = util.nextUid(); - this._navbarProto = null; - this._navbarView = null; this._titleEle = undefined; this._backBtn = undefined; this.disposals = []; // if it's possible to go back from this nav item this.enableBack = false; + + this.protos = {}; + } + + addProtoViewRef(name, protoViewRef) { + this.protos[name] = protoViewRef; } stage() { // update if it's possible to go back from this nav item - this.enableBack = !!this.nav.getPrevious(this); + //this.enableBack = !!this.nav.getPrevious(this); return this.render();; } render() { - console.log('nav-item render') - if (this.created) { + if (this.isRendered) { console.log('showed existing view', this.id); return Promise.resolve(); } - - this.created = true; + this.isRendered = true; let resolve; let promise = new Promise((res) => { resolve = res; }); - let injector = this.nav.injector.resolveAndCreateChild([ - bind(NavController).toValue(this.nav.navCtrl), - bind(NavParams).toValue(new NavParams(this.params)), - bind(NavItem).toValue(this) - ]); + // compile the Component + this.nav.compiler.compileInHost(this.Component).then(componentProtoViewRef => { - this.nav.loader.loadNextToExistingLocation(this.Component, this.nav.contentElementRef, injector).then((componentRef) => { - console.log('nav-item loadNextToExistingLocation', this.nav.contentElementRef) - let navbarContainer = this.nav.navbarContainerRef; + // figure out the sturcture of this Component + // does it have a navbar? Is it tabs? Should it not have a navbar or any toolbars? + let itemStructure = this.getStructure(componentProtoViewRef); - if (componentRef && componentRef.dispose && navbarContainer) { - this.disposals.push(componentRef.dispose); + // get the appropriate NavPane which this NavItem will fit into + this.nav.getNavPane(itemStructure).then(navPane => { - this.viewEle = componentRef.location.domElement; - this.viewEle.classList.add('ion-view'); + // create a new injector just for this NavItem + let injector = this.nav.injector.resolveAndCreateChild([ + bind(NavController).toValue(this.nav.navCtrl), + bind(NavParams).toValue(new NavParams(this.params)), + bind(NavItem).toValue(this) + ]); - if (this._navbarProto) { - let context = { - boundElementIndex: 0, - parentView: { - _view: componentRef.location.parentView._view.componentChildViews[0] - } - }; + // add the content of the view to the content area + let viewContainer = navPane.contentContainerRef; + let hostViewRef = viewContainer.create(componentProtoViewRef, -1, null, injector); - let atIndex = -1; + this.disposals.push(() => { + viewContainer.remove( viewContainer.indexOf(hostViewRef) ); + }); - console.log('nav-item navbarContainer.create', this._navbarProto) - this._navbarView = navbarContainer.create(this._navbarProto, atIndex, context, injector); + this.viewEle = hostViewRef._view.render._view.rootNodes[0]; + this.viewEle.classList.add('nav-item'); - if (this._navbarView) { - this.disposals.push(() => { - navbarContainer.remove( navbarContainer.indexOf(this._navbarView) ); - }); - } + // add only the sections it needs + if (itemStructure.navbar) { + let navbarViewContainer = navPane.sections.navbar.viewContainerRef; + this.navbarView = navbarViewContainer.create(this.protos.navbar, -1, null, injector); + + this.disposals.push(() => { + navbarViewContainer.remove( navbarViewContainer.indexOf(this.navbarView) ); + }); } - } - console.log('created view', this.id); - resolve(); + resolve(); + }); + }); return promise; } + getStructure(componentProtoViewRef) { + // navbar - toolbar - toolbar - content - toolbar - tabbar + let itemStructure = { + navbar: true, + tabbar: false, + toolbars: [], + key: 'c' + }; + + return itemStructure; + } +// if (this.created) { +// console.log('showed existing view', this.id); +// return Promise.resolve(); +// } + +// this.created = true; + +// let resolve; +// let promise = new Promise((res) => { resolve = res; }); + +// let injector = this.nav.injector.resolveAndCreateChild([ +// bind(NavController).toValue(this.nav.navCtrl), +// bind(NavParams).toValue(new NavParams(this.params)), +// bind(NavItem).toValue(this) +// ]); + +// this.nav.loader.loadNextToExistingLocation(this.Component, this.nav.contentElementRef, injector).then((componentRef) => { +// let navbarContainer = this.nav.navbarContainerRef; + +// if (componentRef && componentRef.dispose && navbarContainer) { +// this.disposals.push(componentRef.dispose); + +// this.viewEle = componentRef.location.domElement; +// this.viewEle.classList.add('ion-view'); + +// if (this._navbarProto) { +// let context = { +// boundElementIndex: 0, +// parentView: { +// _view: componentRef.location.parentView._view.componentChildViews[0] +// } +// }; + +// let atIndex = -1; + +// this._navbarView = navbarContainer.create(this._navbarProto, atIndex, context, injector); + +// if (this._navbarView) { +// this.disposals.push(() => { +// navbarContainer.remove( navbarContainer.indexOf(this._navbarView) ); +// }); +// } +// } +// } + +// console.log('created view', this.id); +// resolve(); +// }); + +// return promise; + + cache() { console.log('cached view', this.id); } @@ -114,8 +183,8 @@ export class NavItem { } navbarElement() { - if (this._navbarView && this._navbarView._view) { - return this._navbarView._view.render._view.rootNodes[0]; + if (this.navbarView && this.navbarView._view) { + return this.navbarView._view.render._view.rootNodes[0]; } } @@ -125,14 +194,14 @@ export class NavItem { titleElement() { if (this._titleEle === undefined) { - let navbarElement = this.navbarElement(); - if (navbarElement) { - let titleEle = navbarElement.querySelector('ion-title'); - if (titleEle) { - this._titleEle = titleEle; - return this._titleEle; - } - } + //let navbarElement = this.navbarElement(); + //if (navbarElement) { + // let titleEle = navbarElement.querySelector('ion-title'); + // if (titleEle) { + // this._titleEle = titleEle; + // return this._titleEle; + // } + //} this._titleEle = null; } return this._titleEle; diff --git a/ionic/components/nav/nav.js b/ionic/components/nav/nav.js index 43f957f92a..8713499e9a 100644 --- a/ionic/components/nav/nav.js +++ b/ionic/components/nav/nav.js @@ -5,10 +5,16 @@ import {ElementRef} from 'angular2/src/core/compiler/element_ref'; import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader'; import {Injector} from 'angular2/di'; import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; +import {Compiler} from 'angular2/angular2'; +import {bind} from 'angular2/di'; -import {NavBase} from './nav-base'; +import {NavController} from './nav-controller'; +import {NavItem, NavParams} from './nav-item'; +import {nav} from './nav-base'; import {SwipeHandle} from './swipe-handle'; import {IonicComponent} from '../../config/component'; +import * as util from 'ionic/util'; +import {Transition, ClickBlock} from 'ionic/ionic'; @Component({ @@ -20,60 +26,540 @@ import {IonicComponent} from '../../config/component'; }) @View({ template: ` - -
- - -
+ `, - directives: [NavbarAnchor, ContentAnchor, SwipeHandle] + directives: [NavPaneAnchor] }) export class Nav { - constructor(elementRef: ElementRef, loader: DynamicComponentLoader, injector: Injector) { - this.navBase = new NavBase(elementRef, loader, injector); + constructor(compiler:Compiler, elementRef: ElementRef, loader: DynamicComponentLoader, injector: Injector, viewContainerRef: ViewContainerRef) { + this.compiler = compiler; + this.elementRef = elementRef; + this.loader = loader; + this.injector = injector; + this.viewContainerRef = viewContainerRef; + this.items = []; + this.navCtrl = new NavController(this); + this.sbTransition = null; + this.sbActive = false; this.domElement = elementRef.domElement; this.config = Nav.config.invoke(this); + + this.navPanes = {}; + } + + getNavPane(itemStructure) { + // this gets or creates the NavPane which similar nav items live in + // Nav items with just a navbar/content would all use the same NavPane + // Tabs and view's without a navbar would get a different NavPanes + let resolve; + let promise = new Promise((res) => { resolve = res; }); + + if (this.navPanes[itemStructure.key]) { + // nav pane which the entering component already exists + resolve(this.navPanes[itemStructure.key]); + + } else { + // create a new nav pane + this.navPanes[itemStructure.key] = null; + + // add a NavPane element + // when the NavPane is added, it'll also add its reference to the navPanes object + this.loader.loadNextToExistingLocation(NavPane, this.anchorElementRef, null).then(() => { + + // get the navPane reference by name + let navPane = this.navPanes[itemStructure.key]; + + // get the element inside the NavPane to add sections to + let sectionViewContainerRef = navPane.sectionAnchorElementRef; + let promises = []; + let sectionsToAdd = [] + + // decide which sections should be added to this NavPane, ie: nav bars, tab bars, etc. + // add only the sections it needs + if (itemStructure.navbar) { + sectionsToAdd.push(NavBarSection); + } + + // add the sections which this type of NavPane requires + sectionsToAdd.forEach(SectionClass => { + // as each section is compiled and added to the NavPane + // the section will add a reference to itself in the NavPane's sections object + promises.push( this.loader.loadNextToExistingLocation(SectionClass, sectionViewContainerRef, null) ); + }); + + // wait for all of the sections to resolve + Promise.all(promises).then(() => { + resolve(navPane); + }); + + }); + + } + + return promise; + } + + addNavPane(navPane) { + for (let np in this.navPanes) { + if (this.navPanes[np] === null) { + this.navPanes[np] = navPane; + } + } } onInit() { if (this.initial) { - this.navBase.push(this.initial); + this.push(this.initial); } } + push(Component, params = {}, opts = {}) { + if (this.isTransitioning()) { + return Promise.reject(); + } + + let resolve; + let promise = new Promise(res => { resolve = res; }); + + // default the direction to "forward" + opts.direction = opts.direction || 'forward'; + + if(opts.animate === false) { + opts.animation = 'none'; + } + + // do not animate if this is the first in the stack + if (!this.items.length) { + opts.animation = 'none'; + } + + // the active item is going to be the leaving one (if one exists) + let leavingItem = this.getActive() || {}; + leavingItem.shouldDestroy = false; + + // create a new NavStackItem + let enteringItem = new NavItem(this, Component, params); + + // set that this item is staged (it's not ready to be animated in yet) + enteringItem.state = STAGED_STATE; + enteringItem.shouldDestroy = false; + + // add the item to the stack + this.items.push(enteringItem); + + // start the transition + this.transition(enteringItem, leavingItem, opts).then(() => { + resolve(); + }); + + return promise; + } + + pop(opts = {}) { + if (this.isTransitioning() || this.items.length < 1) { + return Promise.reject(); + } + + if(opts.animate === false) { + opts.animation = 'none'; + } + + let resolve; + let promise = new Promise(res => { resolve = res; }); + + // default the direction to "back" + opts.direction = opts.direction || 'back'; + + // get the active item and set that it is staged to be leaving + // was probably the one popped from the stack + let leavingItem = this.getActive(); + leavingItem.shouldDestroy = true; + + // the entering item is now the new last item + // Note: we might not have an entering item if this is the only + // item on the history stack. + let enteringItem = this.getPrevious(leavingItem); + if(enteringItem) { + enteringItem.shouldDestroy = false; + + // start the transition + this.transition(enteringItem, leavingItem, opts).then(() => { + // transition completed, destroy the leaving item + resolve(); + }); + } else { + this.transitionComplete(); + resolve(); + } + + return promise; + } + + transition(enteringItem, leavingItem, opts) { + let resolve; + let promise = new Promise(res => { resolve = res; }); + + opts.isAnimated = opts.animation !== 'none'; + + this.transitionStart(opts); + + // wait for the new item to complete setup + enteringItem.stage().then(() => { + + // set that the leaving item is stage to be leaving + leavingItem.state = STAGED_LEAVING_STATE; + + // set that the new item pushed on the stack is staged to be entering + // setting staged state is important for the transition logic to find the correct item + enteringItem.state = STAGED_ENTERING_STATE; + + // init the transition animation + let transAnimation = Transition.create(this, opts); + + // wait for the items to be fully staged + transAnimation.stage().then(() => { + + // update the state that the items are actively entering/leaving + enteringItem.state = ACTIVELY_ENTERING_STATE; + leavingItem.state = ACTIVELY_LEAVING_STATE; + + // start the transition + transAnimation.play().then(() => { + + // transition has completed, update each item's state + enteringItem.state = ACTIVE_STATE; + leavingItem.state = CACHED_STATE; + + // dispose any items that shouldn't stay around + transAnimation.dispose(); + + // all done! + this.transitionComplete(); + + // resolve that this push has completed + resolve(); + }); + + }); + + }); + + return promise; + } + + swipeBackStart() { + if (this.isTransitioning() || this.items.length < 2) { + return; + } + + this.sbActive = true; + this.sbResolve = null; + + // default the direction to "back" + let opts = { + direction: 'back' + }; + + // get the active item and set that it is staged to be leaving + // was probably the one popped from the stack + let leavingItem = this.getActive(); + leavingItem.shouldDestroy = true; + + // the entering item is now the new last item + let enteringItem = this.getPrevious(leavingItem); + enteringItem.shouldDestroy = false; + + // start the transition + this.transitionStart({ isAnimated: true }); + + // wait for the new item to complete setup + enteringItem.stage().then(() => { + + // set that the leaving item is stage to be leaving + leavingItem.state = STAGED_LEAVING_STATE; + + // set that the new item pushed on the stack is staged to be entering + // setting staged state is important for the transition logic to find the correct item + enteringItem.state = STAGED_ENTERING_STATE; + + // init the transition animation + this.sbTransition = Transition.create(this, opts); + this.sbTransition.easing('linear'); + + // wait for the items to be fully staged + this.sbTransition.stage().then(() => { + + // update the state that the items are actively entering/leaving + enteringItem.state = ACTIVELY_ENTERING_STATE; + leavingItem.state = ACTIVELY_LEAVING_STATE; + + let swipeBackPromise = new Promise(res => { this.sbResolve = res; }); + + swipeBackPromise.then((completeSwipeBack) => { + + if (completeSwipeBack) { + // swipe back has completed, update each item's state + enteringItem.state = ACTIVE_STATE; + leavingItem.state = CACHED_STATE; + + } else { + // cancelled the swipe back, return items to original state + leavingItem.state = ACTIVE_STATE; + enteringItem.state = CACHED_STATE; + + leavingItem.shouldDestroy = false; + enteringItem.shouldDestroy = false; + } + + // all done! + this.transitionComplete(); + + }); + + }); + + }); + + } + + swipeBackEnd(completeSwipeBack, progress, playbackRate) { + // to reverse the animation use a negative playbackRate + if (this.sbTransition && this.sbActive) { + this.sbActive = false; + + if (progress <= 0) { + this.swipeBackProgress(0.0001); + } else if (progress >= 1) { + this.swipeBackProgress(0.9999); + } + + if (!completeSwipeBack) { + playbackRate = playbackRate * -1; + } + + this.sbTransition.playbackRate(playbackRate); + + this.sbTransition.play().then(() => { + this.sbResolve && this.sbResolve(completeSwipeBack); + this.sbTransition && this.sbTransition.dispose(); + this.sbResolve = this.sbTransition = null; + }); + } + } + + swipeBackProgress(progress) { + if (this.sbTransition) { + ClickBlock(true, 4000); + this.sbTransition.progress( Math.min(1, Math.max(0, progress)) ); + } + } + + transitionStart(opts) { + if (opts.isAnimated) { + // block possible clicks during transition + ClickBlock(true, 520); + this.getNavElement().classList.add('transitioning'); + } + } + + transitionComplete() { + + this.items.forEach((item) => { + if (item) { + if (item.shouldDestroy) { + this.remove(item); + item.destroy(); + + } else if(item.state !== ACTIVE_STATE) { + item.cache(); + } + } + }); + + this.getNavElement().classList.remove('transitioning'); + + // allow clicks again + ClickBlock(false); + } + + isTransitioning() { + let state; + for (let i = 0, ii = this.items.length; i < ii; i++) { + state = this.items[i].state; + if (state === ACTIVELY_ENTERING_STATE || + state === ACTIVELY_LEAVING_STATE || + state === STAGED_ENTERING_STATE || + state === STAGED_LEAVING_STATE) { + return true; + } + } + return false; + } + + clear() { + let pops = []; + for(let item of this.items) { + pops.push(this.pop({ + animate: false + })); + } + return Promise.all(pops); + } + + getActive() { + for (let i = 0, ii = this.items.length; i < ii; i++) { + if (this.items[i].state === ACTIVE_STATE) { + return this.items[i]; + } + } + return null; + } + + getPrevious(item) { + if (item) { + return this.items[ this.items.indexOf(item) - 1 ]; + } + return null; + } + + getStagedEnteringItem() { + for (let i = 0, ii = this.items.length; i < ii; i++) { + if (this.items[i].state === STAGED_ENTERING_STATE) { + return this.items[i]; + } + } + return null; + } + + getStagedLeavingItem() { + for (let i = 0, ii = this.items.length; i < ii; i++) { + if (this.items[i].state === STAGED_LEAVING_STATE) { + return this.items[i]; + } + } + return null; + } + + getNavElement() { + return this.domElement; + } + + remove(itemOrIndex) { + util.array.remove(this.items, itemOrIndex); + } + width() { return this.domElement.offsetWidth; } get swipeBackEnabled() { - let activeItem = this.navBase.getActive(); - if (activeItem) { - return activeItem.enableBack; - } + // let activeItem = this.nav.getActive(); + // if (activeItem) { + // return activeItem.enableBack; + // } return false; } } new IonicComponent(Nav, {}); +// Used to dynamically place new NavPanes next to this +// Which is inside of ion-nav @Directive({ - selector: '[navbar-anchor]' + selector: 'template[nav-pane-anchor]' }) -class NavbarAnchor { - constructor(@Parent() nav: Nav, viewContainerRef: ViewContainerRef) { - nav.navBase.navbarContainerRef = viewContainerRef; - } -} - - -@Directive({ - selector: '[content-anchor]' -}) -class ContentAnchor { +class NavPaneAnchor { constructor(@Parent() nav: Nav, elementRef: ElementRef) { - nav.navBase.contentElementRef = elementRef; + nav.anchorElementRef = elementRef; } } + + + +@Component({selector:'ion-nav-pane'}) +@View({ + template: ` + +
+ +
+ `, + directives: [NavPaneSectionAnchor, NavPaneContentAnchor] +}) +class NavPane { + constructor(@Parent() nav: Nav, viewContainerRef: ViewContainerRef) { + this.viewContainerRef = viewContainerRef; + this.sections = {}; + nav.addNavPane(this); + } + addSection(sectionName, instance) { + this.sections[sectionName] = instance; + } +} + + +// Used to dynamically create new sections for a NavPane +// This is simply a reference point to create new sections +// Navbar, toolbar, and tabbar sections would be created next to this +@Directive({ + selector: 'template[nav-section-anchor]' +}) +class NavPaneSectionAnchor { + constructor(@Parent() navPane: NavPane, elementRef: ElementRef) { + navPane.sectionAnchorElementRef = elementRef; + } +} + + +// Where the content of the NavItem goes next to. All NavPanes have content. +// This is simply a reference point to where content goes +@Directive({ + selector: 'template[content-anchor]' +}) +class NavPaneContentAnchor { + constructor(@Parent() navPane: NavPane, viewContainerRef: ViewContainerRef) { + navPane.contentContainerRef = viewContainerRef; + } +} + + +// +@Component({ + selector: 'section', + hostAttributes: { + 'class': 'navbar-container' + } +}) +@View({ + template: ` + + `, + directives: [NavBarSectionAnchor] +}) +class NavBarSection { + constructor(@Parent() navPane: NavPane, viewContainerRef: ViewContainerRef, elementRef: ElementRef) { + this.navPane = navPane; + navPane.addSection('navbar', this); + } +} + + +// Reference point of where the guts of the NavBar should go next to +@Directive({ + selector: 'template[section-anchor]' +}) +class NavBarSectionAnchor { + constructor(@Parent() navBarSection: NavBarSection, viewContainerRef: ViewContainerRef) { + navBarSection.viewContainerRef = viewContainerRef; + } +} + + +const STAGED_STATE = 'staged'; +const STAGED_ENTERING_STATE = 'staged-enter'; +const STAGED_LEAVING_STATE = 'staged-leave'; +const ACTIVELY_ENTERING_STATE = 'entering'; +const ACTIVELY_LEAVING_STATE = 'leaving'; +const ACTIVE_STATE = 'active'; +const CACHED_STATE = 'cached'; diff --git a/ionic/components/view/view.scss b/ionic/components/view/view.scss index 0af6cdb323..c443a8dd51 100644 --- a/ionic/components/view/view.scss +++ b/ionic/components/view/view.scss @@ -1,5 +1,6 @@ -ion-view, -.ion-view { + +ion-view { + display: flex; position: absolute; top: 0; left: 0; @@ -7,14 +8,4 @@ ion-view, height: 100%; background-color: white; - - // by default this is display: none; - // and the transition animation will display it - //display: none; - flex-direction: column; - - &.show-view { - display: flex; - } - }