diff --git a/ionic/animations/animation.js b/ionic/animations/animation.js index 0649e81bc4..bc31f5355f 100644 --- a/ionic/animations/animation.js +++ b/ionic/animations/animation.js @@ -46,18 +46,11 @@ export class Animation { return this; } - addChild(childAnimation) { - if (childAnimation) { - childAnimation.parent(this); - this._children.push(childAnimation); - } - return this; - } - - children(arr) { - arr = Array.isArray(arr) ? arr : arguments; - for (let i = 0; i < arr.length; i++) { - this.addChild(arr[i]); + addAnimation(childAnimations) { + childAnimations = Array.isArray(childAnimations) ? childAnimations : arguments; + for (let i = 0; i < childAnimations.length; i++) { + childAnimations[i].parent(this); + this._children.push(childAnimations[i]); } return this; } diff --git a/ionic/components.js b/ionic/components.js index 859a6e5087..8cf4a00a49 100644 --- a/ionic/components.js +++ b/ionic/components.js @@ -15,7 +15,7 @@ export * from 'ionic/components/list/list' 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/decorators' +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' @@ -24,4 +24,3 @@ export * from 'ionic/components/segment/segment' export * from 'ionic/components/switch/switch' //export * from 'ionic/components/tabs/tabs' //export * from 'ionic/components/tabs/tab' -export * from 'ionic/components/toolbar/toolbar' diff --git a/ionic/components/app/flex-order.scss b/ionic/components/app/flex-order.scss index 468e86a681..b11c08ae67 100644 --- a/ionic/components/app/flex-order.scss +++ b/ionic/components/app/flex-order.scss @@ -4,11 +4,11 @@ // the rock that everything orders around -$flex-order-view-content: 40 !default; +$flex-order-view-content: 0 !default; -$flex-order-toolbar-top: 20 !default; -$flex-order-toolbar-bottom: 60 !default; +$flex-order-toolbar-top: -10 !default; +$flex-order-toolbar-bottom: 10 !default; $flex-order-tab-bar-top: 30 !default; diff --git a/ionic/components/app/structure.scss b/ionic/components/app/structure.scss index 2c1bbd6abb..fb724f9ec0 100644 --- a/ionic/components/app/structure.scss +++ b/ionic/components/app/structure.scss @@ -33,6 +33,32 @@ ion-nav { width: 100%; height: 100%; overflow: hidden; + + display: flex; + flex-direction: column; +} + +.navbar-container { + position: relative; + min-height: 4.4rem; +} + +.content-container { + position: relative; + flex: 1; +} + +ion-navbar { + position: absolute; + width: 100%; + height: 100%; + min-height: 4.4rem; + order: $flex-order-toolbar-top; + + display: none; + &.show-navbar { + display: flex; + } } ion-view { @@ -55,15 +81,7 @@ ion-view { ion-toolbar { display: flex; min-height: 4.4rem; - order: $flex-order-toolbar-top; -} - -.stage-off { - transform: translateX(9999px); -} - -ion-toolbar[footer] { - order: $flex-order-toolbar-bottom; + background: white; } ion-content { diff --git a/ionic/components/toolbar/back-button.js b/ionic/components/nav-bar/back-button.js similarity index 100% rename from ionic/components/toolbar/back-button.js rename to ionic/components/nav-bar/back-button.js diff --git a/ionic/components/nav-bar/extensions/ios.scss b/ionic/components/nav-bar/extensions/ios.scss new file mode 100644 index 0000000000..7874d92e87 --- /dev/null +++ b/ionic/components/nav-bar/extensions/ios.scss @@ -0,0 +1,70 @@ + +// iOS Navbar +// -------------------------------------------------- + +$navbar-order-ios: ( + back-button: 10, + primary: 20, + title: 30, + secondary: 40 +); + +$navbar-ios-height: 4.4rem !default; +$navbar-ios-background: #f7f7f8 !default; +$navbar-ios-border-color: #c4c4c4 !default; + +$navbar-ios-title-font-size: 1.7rem !default; +$navbar-ios-button-font-size: 1.7rem !default; +$navbar-ios-button-text-color: #007aff !default; +$navbar-ios-button-background-color: transparent !default; + + +.nav-ios .navbar-container { + + height: $navbar-ios-height; + background: $navbar-ios-background; + + // navbar on top, border on bottom (default) + @include hairline(bottom, $navbar-ios-border-color); + + // navbar on bottom, border on top + &.navbar-bottom:after { + top: 0; + bottom: auto; + } + + .navbar [side="primary"] { + order: map-get($navbar-order-ios, 'primary'); + } + + .navbar [side="secondary"] { + order: map-get($navbar-order-ios, 'secondary'); + } + + ion-title { + order: map-get($navbar-order-ios, 'title'); + text-align: center; + font-size: $navbar-ios-title-font-size; + font-weight: 500; + } + + .navbar-back-button { + order: map-get($navbar-order-ios, 'back-button'); + } + + .button { + font-size: $navbar-ios-button-font-size; + color: $navbar-ios-button-text-color; + border: none; + padding: 0; + margin: 0 10px; + min-height: $navbar-ios-height; + min-width: 0; + background: $navbar-ios-button-background-color; + } + + .back-button-icon { + padding-right: 6px; + } + +} diff --git a/ionic/components/nav-bar/extensions/material.scss b/ionic/components/nav-bar/extensions/material.scss new file mode 100644 index 0000000000..72b591e4cd --- /dev/null +++ b/ionic/components/nav-bar/extensions/material.scss @@ -0,0 +1,33 @@ + +// Material Design Navbar +// -------------------------------------------------- + +$navbar-material-height: 6.4rem !default; +$navbar-material-background: #f7f7f8 !default; + +$navbar-material-title-font-size: 2rem !default; +$navbar-material-button-font-size: 2rem !default; +$navbar-material-button-text-color: #007aff !default; + + +.navbar-md { + height: $navbar-material-height; + background: $navbar-material-background; + + .navbar-title { + font-size: $navbar-material-title-font-size; + } + + .button { + font-size: $navbar-material-button-font-size; + color: $navbar-material-button-text-color; + border: none; + + padding: 0; + margin: 0 10px; + + min-height: $navbar-material-height; + min-width: 0; + } + +} diff --git a/ionic/components/toolbar/toolbar.js b/ionic/components/nav-bar/nav-bar.js similarity index 67% rename from ionic/components/toolbar/toolbar.js rename to ionic/components/nav-bar/nav-bar.js index d295f2c4a2..b34ae0c8ac 100644 --- a/ionic/components/toolbar/toolbar.js +++ b/ionic/components/nav-bar/nav-bar.js @@ -3,58 +3,55 @@ import {View} from 'angular2/src/core/annotations_impl/view'; import {ElementRef} from 'angular2/src/core/compiler/element_ref'; import {ProtoViewRef} from 'angular2/src/core/compiler/view_ref'; -import * as dom from 'ionic/util/dom'; -import {IonicComponent} from 'ionic/config/component'; -import {NavItem} from 'ionic/ionic'; +import * as dom from '../../util/dom'; import {Platform} from 'ionic/platform/platform'; +import {NavItem} from '../nav/nav-item'; import {BackButton} from './back-button'; @Component({ - selector: 'ion-toolbar' + selector: 'ion-navbar' }) @View({ template: ` -
- -
-
+
`, directives: [BackButton] }) -export class Toolbar { +export class Navbar { constructor(navItem: NavItem, elementRef: ElementRef) { this.navItem = navItem; this.domElement = elementRef.domElement; - this.config = Toolbar.config.invoke(this); // http://davidwalsh.name/detect-node-insertion dom.animationStart(this.domElement, 'nodeInserted').then(() => { this.alignTitle(); }); - } alignTitle() { - const toolbarEle = this.domElement; - const innerTitleEle = this._innerTitleEle || (this._innerTitleEle = toolbarEle.querySelector('.toolbar-inner-title')); + const navbarEle = this.domElement; + const innerTitleEle = this._innerTitleEle || (this._innerTitleEle = navbarEle.querySelector('.navbar-inner-title')); const titleEle = this._titleEle || (this._titleEle = innerTitleEle.querySelector('ion-title')); const style = this._style || (this._style = window.getComputedStyle(titleEle)); const titleOffsetWidth = titleEle.offsetWidth; const titleOffsetLeft = titleEle.offsetLeft; const titleScrollWidth = titleEle.scrollWidth; - const toolbarOffsetWidth = toolbarEle.offsetWidth; + const navbarOffsetWidth = navbarEle.offsetWidth; // TODO!!! When an element is being reused by angular2, it'll sometimes keep the // styles from the original element's use, causing these calculations to be wrong @@ -68,7 +65,7 @@ export class Toolbar { this._showTitle(); } else { - let rightMargin = toolbarOffsetWidth - (titleOffsetLeft + titleOffsetWidth); + let rightMargin = navbarOffsetWidth - (titleOffsetLeft + titleOffsetWidth); let centerMargin = titleOffsetLeft - rightMargin; innerTitleEle.style.margin = `0 ${centerMargin}px 0 0`; @@ -87,10 +84,23 @@ export class Toolbar { _showTitle() { if (!this._shown) { this._shown = true; - this._innerTitleEle.classList.remove('toolbar-title-hide'); + this._innerTitleEle.classList.remove('navbar-title-hide'); } } - } -new IonicComponent(Toolbar, {}); + + +/* + Used to find and register headers in a view, and this directive's + content will be moved up to the common navbar location, and created + using the same context as the view's content area. +*/ +@Directive({ + selector: 'template[navbar]' +}) +export class NavbarTemplate { + constructor(navItem: NavItem, protoViewRef: ProtoViewRef) { + navItem.navbarProto(protoViewRef); + } +} diff --git a/ionic/components/toolbar/toolbar.scss b/ionic/components/nav-bar/nav-bar.scss similarity index 55% rename from ionic/components/toolbar/toolbar.scss rename to ionic/components/nav-bar/nav-bar.scss index 2892216bc1..acecad5bd2 100644 --- a/ionic/components/toolbar/toolbar.scss +++ b/ionic/components/nav-bar/nav-bar.scss @@ -1,10 +1,8 @@ -// Toolbar +// Navbar // -------------------------------------------------- -$toolbar-background-color: #fff !default; - -$toolbar-order: ( +$navbar-order: ( back-button: 10, title: 20, primary: 30, @@ -12,25 +10,24 @@ $toolbar-order: ( ); -ion-toolbar { - background: $toolbar-background-color; +ion-navbar { flex-direction: row; align-items: center; justify-content: space-between; } -.toolbar-inner { +.navbar-inner { display: flex; width: 100%; } -ion-toolbar back-button.toolbar-item { - order: map-get($toolbar-order, 'back-button'); +ion-navbar back-button.navbar-item { + order: map-get($navbar-order, 'back-button'); } -.toolbar-title { +.navbar-title { flex: 1; - order: map-get($toolbar-order, 'title'); + order: map-get($navbar-order, 'title'); display: flex; align-items: center; @@ -38,13 +35,13 @@ ion-toolbar back-button.toolbar-item { } // buttons are primary by default -ion-toolbar .button, -ion-toolbar [side="primary"] { - order: map-get($toolbar-order, 'primary'); +ion-navbar .button, +ion-navbar [side="primary"] { + order: map-get($navbar-order, 'primary'); } -ion-toolbar [side="secondary"] { - order: map-get($toolbar-order, 'secondary'); +ion-navbar [side="secondary"] { + order: map-get($navbar-order, 'secondary'); } ion-title { @@ -56,18 +53,18 @@ ion-title { animation-name: nodeInserted; } -.toolbar-inner-title { +.navbar-inner-title { width: 100%; padding: 0 15px; white-space: nowrap; text-overflow: ellipsis; } -.toolbar .button { +.navbar .button { background: transparent; border: none; } -.toolbar-title-hide { +.navbar-title-hide { opacity: 0; } diff --git a/ionic/components/toolbar/test/html-title/e2e.js b/ionic/components/nav-bar/test/html-title/e2e.js similarity index 100% rename from ionic/components/toolbar/test/html-title/e2e.js rename to ionic/components/nav-bar/test/html-title/e2e.js diff --git a/ionic/components/toolbar/test/html-title/index.js b/ionic/components/nav-bar/test/html-title/index.js similarity index 100% rename from ionic/components/toolbar/test/html-title/index.js rename to ionic/components/nav-bar/test/html-title/index.js diff --git a/ionic/components/toolbar/test/html-title/main.html b/ionic/components/nav-bar/test/html-title/main.html similarity index 100% rename from ionic/components/toolbar/test/html-title/main.html rename to ionic/components/nav-bar/test/html-title/main.html diff --git a/ionic/components/toolbar/test/long-title/e2e.js b/ionic/components/nav-bar/test/long-title/e2e.js similarity index 100% rename from ionic/components/toolbar/test/long-title/e2e.js rename to ionic/components/nav-bar/test/long-title/e2e.js diff --git a/ionic/components/toolbar/test/long-title/index.js b/ionic/components/nav-bar/test/long-title/index.js similarity index 100% rename from ionic/components/toolbar/test/long-title/index.js rename to ionic/components/nav-bar/test/long-title/index.js diff --git a/ionic/components/toolbar/test/long-title/main.html b/ionic/components/nav-bar/test/long-title/main.html similarity index 100% rename from ionic/components/toolbar/test/long-title/main.html rename to ionic/components/nav-bar/test/long-title/main.html diff --git a/ionic/components/toolbar/test/lopsided-buttons/e2e.js b/ionic/components/nav-bar/test/lopsided-buttons/e2e.js similarity index 100% rename from ionic/components/toolbar/test/lopsided-buttons/e2e.js rename to ionic/components/nav-bar/test/lopsided-buttons/e2e.js diff --git a/ionic/components/toolbar/test/lopsided-buttons/index.js b/ionic/components/nav-bar/test/lopsided-buttons/index.js similarity index 100% rename from ionic/components/toolbar/test/lopsided-buttons/index.js rename to ionic/components/nav-bar/test/lopsided-buttons/index.js diff --git a/ionic/components/toolbar/test/lopsided-buttons/main.html b/ionic/components/nav-bar/test/lopsided-buttons/main.html similarity index 100% rename from ionic/components/toolbar/test/lopsided-buttons/main.html rename to ionic/components/nav-bar/test/lopsided-buttons/main.html diff --git a/ionic/components/nav/nav-item.js b/ionic/components/nav/nav-item.js index 3a5d1dfaf5..ffeb853ec1 100644 --- a/ionic/components/nav/nav-item.js +++ b/ionic/components/nav/nav-item.js @@ -3,9 +3,6 @@ import {bind} from 'angular2/di'; import * as util from 'ionic/util'; import {NavController} from './nav-controller'; -import {NavView} from './nav-view'; - -const SHOW_VIEW_CSS = 'show-view'; export class NavItem { @@ -15,9 +12,11 @@ export class NavItem { this.Component = Component; this.params = params; this.id = util.nextUid(); - this.headerProtos = []; - this.toolbarViews = []; + 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; @@ -27,16 +26,12 @@ export class NavItem { // update if it's possible to go back from this nav item this.enableBack = !!this.nav.getPrevious(this); - return this.create().then(() => { - return new Promise(resolve => { - this.viewEle && this.viewEle.classList.add(SHOW_VIEW_CSS); - resolve(); - }); - }); + return this.render();; } - create() { + render() { if (this.created) { + console.log('showed existing view', this.id); return Promise.resolve(); } @@ -51,41 +46,80 @@ export class NavItem { bind(NavItem).toValue(this) ]); - this.nav.loader.loadNextToExistingLocation(this.Component, this.nav.viewElementRef, injector).then((componentRef) => { + this.nav.loader.loadNextToExistingLocation(this.Component, this.nav.contentElementRef, injector).then((componentRef) => { - // content - this.component = componentRef; + let navbarContainer = this.nav.navbarContainerRef; - this.viewEle = componentRef.location.domElement; - this.viewEle.setAttribute('id', 'view-' + this.id); + if (componentRef && componentRef.dispose && navbarContainer) { + this.disposals.push(componentRef.dispose); - if (componentRef && componentRef.dispose) { - this._dispose = componentRef.dispose; + this.viewEle = componentRef.location.domElement; + + 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); + } + + destroy() { + console.log('destroyed view', this.id); + + for (let i = 0; i < this.disposals.length; i++) { + this.disposals[i](); + } + + // just to help prevent any possible memory leaks + for (let name in this) { + if (this.hasOwnProperty(name)) { + this[name] = null; + } + } + } + + navbarProto(navbarProtoView) { + this._navbarProto = navbarProtoView; + } + viewElement() { return this.viewEle; } + navbarElement() { + return this._navbarView._view.render._view.rootNodes[0]; + } + contentElement() { return this.viewEle.querySelector('ion-content'); } - toolbarElements() { - return this.viewEle.querySelectorAll('ion-toolbar'); - } - titleElement() { if (this._titleEle === undefined) { - let toolbarElements = this.toolbarElements(); - for (let i = 0; i < toolbarElements.length; i++) { - var titleEle = toolbarElements[i].querySelector('ion-title'); + let navbarElement = this.navbarElement(); + if (navbarElement) { + let titleEle = navbarElement.querySelector('ion-title'); if (titleEle) { this._titleEle = titleEle; return this._titleEle; @@ -98,9 +132,9 @@ export class NavItem { backButtonElement() { if (this._backBtn === undefined) { - let toolbarElements = this.toolbarElements(); - for (let i = 0; i < toolbarElements.length; i++) { - var backBtn = toolbarElements[i].querySelector('back-button'); + let navbarElement = this.navbarElement(); + if (navbarElement) { + let backBtn = navbarElement.querySelector('back-button'); if (backBtn) { this._backBtn = backBtn; return this._backBtn; @@ -111,21 +145,6 @@ export class NavItem { return this._backBtn; } - cache() { - this.viewEle.classList.remove(SHOW_VIEW_CSS); - } - - destroy() { - this._dispose && this._dispose(); - - // just to help prevent any possible memory leaks - for (let name in this) { - if (this.hasOwnProperty(name)) { - this[name] = null; - } - } - } - } export class NavParams { diff --git a/ionic/components/nav/nav.js b/ionic/components/nav/nav.js index 2622d7deb8..9a5e98a4f5 100644 --- a/ionic/components/nav/nav.js +++ b/ionic/components/nav/nav.js @@ -7,7 +7,7 @@ import {Injector} from 'angular2/di'; import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; import {NavBase} from './nav-base'; -import {ToolbarContainer} from '../toolbar/toolbar-container'; +import {IonicComponent} from 'ionic/config/component' @Component({ @@ -17,26 +17,45 @@ import {ToolbarContainer} from '../toolbar/toolbar-container'; } }) @View({ - template: ``, - directives: [ViewAnchor] + template: ` + +
+ +
+ `, + directives: [NavbarAnchor, ContentAnchor] }) export class Nav extends NavBase { constructor(elementRef: ElementRef, loader: DynamicComponentLoader, injector: Injector) { super(loader, injector); this.domElement = elementRef.domElement; + this.config = Nav.config.invoke(this); } width() { return this.domElement.offsetWidth; } } +new IonicComponent(Nav, {}); @Directive({ - selector: '[view-anchor]' + selector: '[navbar-anchor]' }) -class ViewAnchor { - constructor(@Ancestor() nav: Nav, elementRef: ElementRef) { - nav.viewElementRef = elementRef; +class NavbarAnchor { + constructor(@Ancestor() nav: Nav, viewContainerRef: ViewContainerRef) { + nav.navbarContainerRef = viewContainerRef; + } +} + + +@Directive({ + selector: '[content-anchor]' +}) +class ContentAnchor { + constructor(@Ancestor() nav: Nav, elementRef: ElementRef) { + nav.contentElementRef = elementRef; } } diff --git a/ionic/components/nav/test/basic/main.html b/ionic/components/nav/test/basic/main.html index 946b4caa4a..94cd0153aa 100644 --- a/ionic/components/nav/test/basic/main.html +++ b/ionic/components/nav/test/basic/main.html @@ -1,14 +1,2 @@ - - - + diff --git a/ionic/components/nav/test/basic/pages/first-page.html b/ionic/components/nav/test/basic/pages/first-page.html index 2202e4452b..7db5b18498 100644 --- a/ionic/components/nav/test/basic/pages/first-page.html +++ b/ionic/components/nav/test/basic/pages/first-page.html @@ -1,5 +1,9 @@ -First Page: {{ val }} +First Page Header: {{ val }} + + diff --git a/ionic/components/nav/test/basic/pages/first-page.js b/ionic/components/nav/test/basic/pages/first-page.js index 69079a6509..b11311121a 100644 --- a/ionic/components/nav/test/basic/pages/first-page.js +++ b/ionic/components/nav/test/basic/pages/first-page.js @@ -1,14 +1,14 @@ import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations'; import {View} from 'angular2/src/core/annotations_impl/view'; -import {NavController, Toolbar, Content} from 'ionic/ionic'; +import {NavController, NavbarTemplate, Navbar, Content} from 'ionic/ionic'; import {SecondPage} from './second-page'; @Component({selector: 'ion-view'}) @View({ templateUrl: 'pages/first-page.html', - directives: [Toolbar, Content] + directives: [NavbarTemplate, Navbar, Content] }) export class FirstPage { constructor( diff --git a/ionic/components/nav/test/basic/pages/second-page.html b/ionic/components/nav/test/basic/pages/second-page.html index ba65c683aa..66dba74a1d 100644 --- a/ionic/components/nav/test/basic/pages/second-page.html +++ b/ionic/components/nav/test/basic/pages/second-page.html @@ -1,6 +1,13 @@ -Second Page +Second Page Header + @@ -13,3 +20,12 @@

+ + diff --git a/ionic/components/nav/test/basic/pages/second-page.js b/ionic/components/nav/test/basic/pages/second-page.js index d7be2e1ef0..22de60bda8 100644 --- a/ionic/components/nav/test/basic/pages/second-page.js +++ b/ionic/components/nav/test/basic/pages/second-page.js @@ -1,14 +1,14 @@ import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations'; import {View} from 'angular2/src/core/annotations_impl/view'; -import {NavController, NavParams, Toolbar, Content} from 'ionic/ionic'; +import {NavController, NavParams, NavbarTemplate, Navbar, Content} from 'ionic/ionic'; import {ThirdPage} from './third-page'; @Component({selector: 'ion-view'}) @View({ templateUrl: 'pages/second-page.html', - directives: [Toolbar, Content] + directives: [NavbarTemplate, Navbar, Content] }) export class SecondPage { constructor( diff --git a/ionic/components/nav/test/basic/pages/third-page.html b/ionic/components/nav/test/basic/pages/third-page.html index c5e9badd5b..274f25ab71 100644 --- a/ionic/components/nav/test/basic/pages/third-page.html +++ b/ionic/components/nav/test/basic/pages/third-page.html @@ -1,6 +1,9 @@ -Third Page +Third Page Header + diff --git a/ionic/components/nav/test/basic/pages/third-page.js b/ionic/components/nav/test/basic/pages/third-page.js index 11b4db9900..26c1e2f830 100644 --- a/ionic/components/nav/test/basic/pages/third-page.js +++ b/ionic/components/nav/test/basic/pages/third-page.js @@ -1,13 +1,13 @@ import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations'; import {View} from 'angular2/src/core/annotations_impl/view'; -import {NavController, Toolbar, Content} from 'ionic/ionic'; +import {NavController, NavbarTemplate, Navbar, Content} from 'ionic/ionic'; @Component({selector: 'ion-view'}) @View({ templateUrl: 'pages/third-page.html', - directives: [Toolbar, Content] + directives: [NavbarTemplate, Navbar, Content] }) export class ThirdPage { constructor( diff --git a/ionic/components/tabs/extensions/ios.scss b/ionic/components/tabs/extensions/ios.scss index 359db26ddc..627d3ebe42 100644 --- a/ionic/components/tabs/extensions/ios.scss +++ b/ionic/components/tabs/extensions/ios.scss @@ -1,5 +1,5 @@ -// iOS Toolbar +// iOS Tab Bar // -------------------------------------------------- $tab-bar-ios-item-padding: 3px 10px !default; @@ -22,14 +22,14 @@ $tab-bar-ios-item-icon-size: 2.8rem !default; } &[tab-bar-placement="bottom"] > .tab-bar-container { - @include hairline(top, $toolbar-ios-border-color); + @include hairline(top, $navbar-ios-border-color); } &[tab-bar-placement="top"] > .tab-bar-container { - @include hairline(bottom, $toolbar-ios-border-color); + @include hairline(bottom, $navbar-ios-border-color); } - &[tab-bar-placement="top"] > .toolbar-container .toolbar { + &[tab-bar-placement="top"] > .navbar-container .navbar { @include hairline(bottom, none); } diff --git a/ionic/components/toolbar/extensions/ios.scss b/ionic/components/toolbar/extensions/ios.scss deleted file mode 100644 index 01be2ca2e9..0000000000 --- a/ionic/components/toolbar/extensions/ios.scss +++ /dev/null @@ -1,73 +0,0 @@ - -// iOS Toolbar -// -------------------------------------------------- - -$toolbar-order-ios: ( - back-button: 10, - primary: 20, - title: 30, - secondary: 40 -); - -$toolbar-ios-height: 4.4rem !default; -$toolbar-ios-background: #f7f7f8 !default; -$toolbar-ios-border-color: #c4c4c4 !default; - -$toolbar-ios-title-font-size: 1.7rem !default; -$toolbar-ios-button-font-size: 1.7rem !default; -$toolbar-ios-button-text-color: #007aff !default; -$toolbar-ios-button-background-color: transparent !default; - - -.toolbar-container-ios { - height: $toolbar-ios-height; - background: $toolbar-ios-background; - - // toolbar on top, border on bottom (default) - @include hairline(bottom, $toolbar-ios-border-color); - - // toolbar on bottom, border on top - &.toolbar-bottom:after { - top: 0; - bottom: auto; - } -} - - -.toolbar-ios { - - .toolbar [side="primary"] { - order: map-get($toolbar-order-ios, 'primary'); - } - - .toolbar [side="secondary"] { - order: map-get($toolbar-order-ios, 'secondary'); - } - - ion-title { - order: map-get($toolbar-order-ios, 'title'); - text-align: center; - font-size: $toolbar-ios-title-font-size; - font-weight: 500; - } - - .toolbar-back-button { - order: map-get($toolbar-order-ios, 'back-button'); - } - - .button { - font-size: $toolbar-ios-button-font-size; - color: $toolbar-ios-button-text-color; - border: none; - padding: 0; - margin: 0 10px; - min-height: $toolbar-ios-height; - min-width: 0; - background: $toolbar-ios-button-background-color; - } - - .back-button-icon { - padding-right: 6px; - } - -} diff --git a/ionic/components/toolbar/extensions/material.scss b/ionic/components/toolbar/extensions/material.scss deleted file mode 100644 index 2dec56d038..0000000000 --- a/ionic/components/toolbar/extensions/material.scss +++ /dev/null @@ -1,33 +0,0 @@ - -// Material Design Toolbar -// -------------------------------------------------- - -$toolbar-material-height: 6.4rem !default; -$toolbar-material-background: #f7f7f8 !default; - -$toolbar-material-title-font-size: 2rem !default; -$toolbar-material-button-font-size: 2rem !default; -$toolbar-material-button-text-color: #007aff !default; - - -.toolbar-md { - height: $toolbar-material-height; - background: $toolbar-material-background; - - .toolbar-title { - font-size: $toolbar-material-title-font-size; - } - - .button { - font-size: $toolbar-material-button-font-size; - color: $toolbar-material-button-text-color; - border: none; - - padding: 0; - margin: 0 10px; - - min-height: $toolbar-material-height; - min-width: 0; - } - -} diff --git a/ionic/components/toolbar/toolbar-container.js b/ionic/components/toolbar/toolbar-container.js deleted file mode 100644 index c92dac4ca1..0000000000 --- a/ionic/components/toolbar/toolbar-container.js +++ /dev/null @@ -1,18 +0,0 @@ -import {ElementRef} from 'angular2/angular2' -import {Directive} from 'angular2/src/core/annotations_impl/annotations'; - -import {IonicComponent} from 'ionic/config/component' - - -@Directive({ - selector: '.toolbar-container' -}) -export class ToolbarContainer { - constructor(elementRef: ElementRef) { - this.domElement = elementRef.domElement; - this.config = ToolbarContainer.config.invoke(this); - } -} - - -new IonicComponent(ToolbarContainer, {}) diff --git a/ionic/ionic.js b/ionic/ionic.js index 37d56a166d..d8d62e19a1 100644 --- a/ionic/ionic.js +++ b/ionic/ionic.js @@ -1,32 +1,11 @@ -// HACKYFILLS (hack + polyfill) -import {NgElement, ViewContainerRef} from 'angular2/angular2' -//import {DomRenderedElement} from 'ionic/util/render/dom'; - -/* -Object.defineProperties(NgElement.prototype, { - renderElement: { - get: function() { - return new DomRenderedElement(this._view.render.delegate.boundElements[this._boundElementIndex]); - } - }, - domElement: { - get: function() { - console.log('GETTING DOM ELEMENT'); - return this._view.render.delegate.boundElements[this._boundElementIndex]; - } - } -}); -*/ - - -Object.defineProperties(ViewContainerRef.prototype, { - domElement: { - get: function() { - return this._defaultProtoView.render.delegate.element; - } - } -}); +// Object.defineProperties(ViewContainerRef.prototype, { +// domElement: { +// get: function() { +// return this._defaultProtoView.render.delegate.element; +// } +// } +// }); export * from 'ionic/components' @@ -43,5 +22,4 @@ export * from 'ionic/engine/electron/electron' export * from 'ionic/animations/animation' export * from 'ionic/transitions/transition' -export * from 'ionic/transitions/none-transition' export * from 'ionic/transitions/ios-transition' diff --git a/ionic/ionic.scss b/ionic/ionic.scss index 5a72da4155..67a63d6f1a 100644 --- a/ionic/ionic.scss +++ b/ionic/ionic.scss @@ -39,18 +39,18 @@ "components/layout/layout", "components/list/list", "components/modal/modal", + "components/nav-bar/nav-bar", "components/slides/slides", "components/radio/radio", "components/search-bar/search-bar", "components/segment/segment", "components/switch/switch", - "components/tabs/tabs", - "components/toolbar/toolbar"; + "components/tabs/tabs"; // iOS Components @import - "components/toolbar/extensions/ios", + "components/nav-bar/extensions/ios", "components/action-menu/extensions/ios", "components/alert/extensions/ios", "components/button/extensions/ios", @@ -70,8 +70,7 @@ @import "components/alert/extensions/material", "components/button/extensions/material", - "components/tabs/extensions/material", - "components/toolbar/extensions/material"; + "components/tabs/extensions/material"; // Icons diff --git a/ionic/transitions/ios-transition.js b/ionic/transitions/ios-transition.js index 453f1b57e4..3ca54fa640 100644 --- a/ionic/transitions/ios-transition.js +++ b/ionic/transitions/ios-transition.js @@ -1,6 +1,5 @@ -import {Animation} from '../animations/animation'; -import {rafPromise} from '../util/dom'; import {Transition} from './transition'; +import {Animation} from '../animations/animation'; const DURATION = 500; @@ -14,128 +13,89 @@ const OFF_LEFT = '-33%'; const CENTER = '0%' const OFF_OPACITY = 0.8; -const SHOW_TOOLBAR_CSS = 'show-toolbar'; -const SHOW_NAV_ITEM_CSS = 'show-nav-item'; - -class IOSTransition extends Animation { +class IOSTransition extends Transition { constructor(navCtrl, opts) { - super(); + super(navCtrl); // global duration and easing for all child animations this.duration(DURATION); this.easing(EASING); - // get the entering and leaving items - let enteringItem = navCtrl.getStagedEnteringItem(); - let leavingItem = navCtrl.getStagedLeavingItem(); - - // create animation for the entering content - let enteringContent = new Animation(enteringItem.contentElement()); - - // create animation for the entering toolbars - let enteringToolbars = new Animation(enteringItem.toolbarElements()); - - // create animation for the entering title element - let enteringTitle = new Animation(enteringItem.titleElement()); - - // create animation for the leaving content - // leavingItem could be null, but the animation instance knows to do nothing - let leavingContent = new Animation(leavingItem && leavingItem.contentElement()); - - // create animation for the leaving content - // leavingItem could be null, but the animation instance knows to do nothing - let leavingToolbars = new Animation(leavingItem && leavingItem.toolbarElements()); - - // create animation for the entering title element - let leavingTitle = new Animation(leavingItem && leavingItem.titleElement()); - // entering item moves to center // before starting, set enteringItem to display: block - enteringContent - .beforePlay.addClass(SHOW_NAV_ITEM_CSS) + this.enteringContent .to(TRANSLATEX, CENTER) .to(OPACITY, 1); - enteringTitle + this.enteringTitle .from(OPACITY, 0) .to(OPACITY, 1) .to(TRANSLATEX, CENTER); - enteringToolbars - .beforePlay.addClass(SHOW_TOOLBAR_CSS); - // if the back button should show, then fade it in - if (enteringItem.enableBack) { - let enteringBackButton = new Animation(enteringItem.backButtonElement()) - enteringBackButton.from(OPACITY, 0).to(OPACITY, 1); - this.addChild(enteringBackButton); + if (this.entering.enableBack) { + let enteringBackButton = new Animation(this.entering.backButtonElement()) + enteringBackButton + .from(OPACITY, 0) + .to(OPACITY, 1); + this.addAnimation(enteringBackButton); } // leaving view moves off screen - // when completed, set leavingItem to display: none - leavingContent - .afterFinish.removeClass(SHOW_NAV_ITEM_CSS) + // when completed, set leaving to display: none + this.leavingContent .from(TRANSLATEX, CENTER) .from(OPACITY, 1); - leavingToolbars - .afterFinish.removeClass(SHOW_TOOLBAR_CSS); - - leavingTitle + this.leavingTitle .from(TRANSLATEX, CENTER) .from(OPACITY, 1); - if (leavingItem) { - let leavingBackButton = new Animation(leavingItem.backButtonElement()); - leavingBackButton.from(OPACITY, 1).to(OPACITY, 0); - this.addChild(leavingBackButton); - } + let leavingBackButton = new Animation(this.leaving.backButtonElement()); + leavingBackButton + .from(OPACITY, 1) + .to(OPACITY, 0); + this.addAnimation(leavingBackButton); // set properties depending on direction if (opts.direction === 'back') { // back direction - enteringContent + this.enteringContent .from(TRANSLATEX, OFF_LEFT) .from(OPACITY, OFF_OPACITY) .to(OPACITY, 1); - enteringTitle + this.enteringTitle .from(TRANSLATEX, OFF_LEFT); - leavingContent + this.leavingContent .to(TRANSLATEX, OFF_RIGHT) .to(OPACITY, 1); - leavingTitle + this.leavingTitle .to(TRANSLATEX, OFF_RIGHT) .to(OPACITY, 0); } else { // forward direction - enteringContent + this.enteringContent .from(TRANSLATEX, OFF_RIGHT) .from(OPACITY, 1); - enteringTitle + this.enteringTitle .from(TRANSLATEX, OFF_RIGHT); - leavingContent + this.leavingContent .to(TRANSLATEX, OFF_LEFT) .to(OPACITY, OFF_OPACITY); - leavingTitle + this.leavingTitle .to(TRANSLATEX, OFF_LEFT) .to(OPACITY, 0); } - // set child animations - this.children(enteringContent, enteringToolbars, enteringTitle, leavingContent, leavingToolbars, leavingTitle); - } - - stage() { - return rafPromise(); } } diff --git a/ionic/transitions/none-transition.js b/ionic/transitions/none-transition.js deleted file mode 100644 index 1e95f296a9..0000000000 --- a/ionic/transitions/none-transition.js +++ /dev/null @@ -1,19 +0,0 @@ -import {Animation} from '../animations/animation'; -import {Transition} from './transition'; -import {rafPromise} from '../util/dom'; - - -class NoneTransition extends Animation { - - constructor(navCtrl) { - super(); - } - - stage() { - // immediately resolve - return rafPromise(); - } - -} - -Transition.register('none', NoneTransition); diff --git a/ionic/transitions/transition.js b/ionic/transitions/transition.js index 85ed4d4269..c1a50e950b 100644 --- a/ionic/transitions/transition.js +++ b/ionic/transitions/transition.js @@ -1,23 +1,80 @@ +import {Animation} from '../animations/animation'; +import {rafPromise} from '../util/dom'; + +const SHOW_NAVBAR_CSS = 'show-navbar'; +const SHOW_VIEW_CSS = 'show-view'; + let registry = {}; -class TransitionController { +export class Transition extends Animation { - create(navCtrl, opts = {}) { + constructor(navCtrl) { + super(); + + // get the entering and leaving items + let enteringItem = this.entering = navCtrl.getStagedEnteringItem(); + let leavingItem = this.leaving = navCtrl.getStagedLeavingItem(); + + // create animation for the entering item's "ion-view" element + this.enteringView = new Animation(enteringItem.viewElement()); + this.enteringView.beforePlay.addClass(SHOW_VIEW_CSS); + + // create animation for the entering item's "ion-navbar" element + this.enteringNavbar = new Animation(enteringItem.navbarElement()); + this.enteringNavbar.beforePlay.addClass(SHOW_NAVBAR_CSS); + + // create animation for the entering item's "ion-content" element + this.enteringContent = new Animation(enteringItem.contentElement()); + + // create animation for the entering item's "ion-title" element + this.enteringTitle = new Animation(enteringItem.titleElement()); + + this.addAnimation(this.enteringView, this.enteringNavbar, this.enteringContent, this.enteringTitle); + + if (leavingItem) { + // create animation for the entering item's "ion-view" element + this.leavingView = new Animation(leavingItem.viewElement()); + this.leavingView.afterFinish.removeClass(SHOW_VIEW_CSS); + + // create animation for the entering item's "ion-navbar" element + this.leavingNavbar = new Animation(leavingItem.navbarElement()); + this.leavingNavbar.afterFinish.removeClass(SHOW_NAVBAR_CSS); + + // create animation for the leaving item's "ion-content" element + this.leavingContent = new Animation(leavingItem.contentElement()); + + // create animation for the leaving item's "ion-title" element + this.leavingTitle = new Animation(leavingItem.titleElement()); + + this.addAnimation(this.leavingView, this.leavingNavbar, this.leavingContent, this.leavingTitle); + } + + } + + stage() { + return rafPromise(); + } + + + /* + STATIC CLASSES + */ + static create(navCtrl, opts = {}) { let name = opts.animation || 'ios'; let TransitionClass = registry[name]; if (!TransitionClass) { - TransitionClass = registry['none']; + // transition wasn't found, default to a 'none' transition + // which doesn't animate anything, just shows and hides + TransitionClass = Transition; } return new TransitionClass(navCtrl, opts); } - register(name, transitionClass) { - registry[name] = transitionClass; + static register(name, TransitionClass) { + registry[name] = TransitionClass; } } - -export let Transition = new TransitionController();