From 76e84bfaac61b0064467dd18eb56a1b2f0468e64 Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Tue, 19 May 2015 21:59:49 -0500 Subject: [PATCH] indiana jones and the toolbar crusade --- ionic/animations/animation.js | 9 +++--- ionic/components/app/structure.scss | 1 + ionic/components/nav/nav-item.js | 15 +++++++++ ionic/components/toolbar/extensions/ios.scss | 5 +-- ionic/components/toolbar/toolbar.js | 27 +++++++++-------- ionic/components/toolbar/toolbar.scss | 2 +- ionic/transitions/ios-transition.js | 32 ++++++++++++++------ ionic/util/util.js | 1 + 8 files changed, 61 insertions(+), 31 deletions(-) diff --git a/ionic/animations/animation.js b/ionic/animations/animation.js index b6b76dbec3..bcc74c8900 100644 --- a/ionic/animations/animation.js +++ b/ionic/animations/animation.js @@ -79,7 +79,7 @@ export class Animation { from(property, value) { if (!this._from) { - this._from = {} + this._from = {}; } this._from[property] = value; return this; @@ -87,7 +87,7 @@ export class Animation { to(property, value) { if (!this._to) { - this._to = {} + this._to = {}; } this._to[property] = value; return this; @@ -127,8 +127,7 @@ export class Animation { } if (!this._to) { - // probably just add/removing classes - // create bogus transition + // probably just add/removing classes, create bogus transition this._from = this._to = {'opacity': 1}; } @@ -215,7 +214,7 @@ class Animate { fromEffect = fromEffect || {}; let style = null; for (let prop in toEffect) { - if (!fromEffect[prop]) { + if (util.isBlank(fromEffect[prop])) { style = style || window.getComputedStyle(ele); fromEffect[prop] = style[prop]; } diff --git a/ionic/components/app/structure.scss b/ionic/components/app/structure.scss index 91190fffe3..3ad00767be 100644 --- a/ionic/components/app/structure.scss +++ b/ionic/components/app/structure.scss @@ -36,6 +36,7 @@ ion-nav { display: flex; flex-direction: column; + overflow: hidden; } .toolbar-container { diff --git a/ionic/components/nav/nav-item.js b/ionic/components/nav/nav-item.js index 5b985d1e1b..1a121de640 100644 --- a/ionic/components/nav/nav-item.js +++ b/ionic/components/nav/nav-item.js @@ -125,6 +125,21 @@ export class NavItem { return this._titleEle; } + getBackButton() { + if (this._backBtn === undefined) { + let toolbarElements = this.getToolbars(); + for (let i = 0; i < toolbarElements.length; i++) { + var backBtn = toolbarElements[i].querySelector('back-button'); + if (backBtn) { + this._backBtn = backBtn; + return this._backBtn; + } + } + this._backBtn = null; + } + return this._backBtn; + } + destroy() { for (let i = 0; i < this.disposals.length; i++) { this.disposals[i](); diff --git a/ionic/components/toolbar/extensions/ios.scss b/ionic/components/toolbar/extensions/ios.scss index 2d199a3d45..de521ddcb3 100644 --- a/ionic/components/toolbar/extensions/ios.scss +++ b/ionic/components/toolbar/extensions/ios.scss @@ -44,12 +44,9 @@ $toolbar-ios-button-background-color: transparent !default; order: map-get($toolbar-order-ios, 'secondary'); } - .toolbar-title { - text-align: center; - } - ion-title { order: map-get($toolbar-order-ios, 'title'); + text-align: center; font-size: $toolbar-ios-title-font-size; font-weight: 500; } diff --git a/ionic/components/toolbar/toolbar.js b/ionic/components/toolbar/toolbar.js index a08ef29f0f..c0a4d6287b 100644 --- a/ionic/components/toolbar/toolbar.js +++ b/ionic/components/toolbar/toolbar.js @@ -49,28 +49,31 @@ export class Toolbar { alignTitle() { if (!this.domElement) return; - const toolbarElement = this.domElement; - const titleElement = this._titleElement || (this._titleElement = toolbarElement.querySelector('.toolbar-inner-title')); - const style = this._style || (this._style = window.getComputedStyle(titleElement)); + const toolbarEle = this.domElement; + const innerTitleEle = this._innerTitleEle || (this._innerTitleEle = toolbarEle.querySelector('.toolbar-inner-title')); + const titleEle = this._titleEle || (this._titleEle = innerTitleEle.querySelector('ion-title')); + const style = this._style || (this._style = window.getComputedStyle(titleEle)); - const titleOffsetWidth = titleElement.offsetWidth; - const titleOffsetLeft = titleElement.offsetLeft; - const titleScrollWidth = titleElement.scrollWidth; - const toolbarOffsetWidth = toolbarElement.offsetWidth; + const titleOffsetWidth = titleEle.offsetWidth; + const titleOffsetLeft = titleEle.offsetLeft; + const titleScrollWidth = titleEle.scrollWidth; + const toolbarOffsetWidth = toolbarEle.offsetWidth; // only align if the title is center and if it isn't already overflowing if (style.textAlign !== 'center' || titleOffsetWidth < titleScrollWidth) { this._showTitle(); + } else { let rightMargin = toolbarOffsetWidth - (titleOffsetLeft + titleOffsetWidth); let centerMargin = titleOffsetLeft - rightMargin; - titleElement.style.margin = `0 ${centerMargin}px 0 0`; + innerTitleEle.style.margin = `0 ${centerMargin}px 0 0`; dom.raf(() => { - if (titleElement.offsetWidth < titleElement.scrollWidth) { - this.titleElement.style.margin = ''; - this.titleElement.style.textAlign = 'left'; + if (titleEle.offsetWidth < titleEle.scrollWidth) { + // not enough room yet, just left align title + innerTitleEle.style.margin = ''; + innerTitleEle.style.textAlign = 'left'; } this._showTitle(); }) @@ -80,7 +83,7 @@ export class Toolbar { _showTitle() { if (!this._shown) { this._shown = true; - this._titleElement.classList.remove('toolbar-title-hide'); + this._innerTitleEle.classList.remove('toolbar-title-hide'); } } diff --git a/ionic/components/toolbar/toolbar.scss b/ionic/components/toolbar/toolbar.scss index 7960358408..e586b69389 100644 --- a/ionic/components/toolbar/toolbar.scss +++ b/ionic/components/toolbar/toolbar.scss @@ -59,6 +59,7 @@ ion-toolbar [side="secondary"] { ion-title { display: block; + overflow: hidden; // used to notify JS when the title has been rendered animation-duration: 1ms; @@ -68,7 +69,6 @@ ion-title { .toolbar-inner-title { width: 100%; padding: 0 15px; - overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } diff --git a/ionic/transitions/ios-transition.js b/ionic/transitions/ios-transition.js index ff335e904f..538ef6f656 100644 --- a/ionic/transitions/ios-transition.js +++ b/ionic/transitions/ios-transition.js @@ -3,8 +3,8 @@ import {rafPromise} from '../util/dom' import {Transition} from './transition' -const EASING_FN = [.36, .66, .04, 1]; const DURATION = 500; +const EASING = 'cubic-bezier(.36,.66,.04,1)'; const OPACITY = 'opacity'; const TRANSFORM = 'transform'; @@ -25,30 +25,31 @@ class IOSTransition extends Animation { // global duration and easing for all child animations this.duration(DURATION); + this.easing(EASING); // get the entering and leaving items - this.enteringItem = navCtrl.getStagedEnteringItem(); - this.leavingItem = navCtrl.getStagedLeavingItem(); + let enteringItem = navCtrl.getStagedEnteringItem(); + let leavingItem = navCtrl.getStagedLeavingItem(); // create animation for the entering content - let enteringContent = new Animation(this.enteringItem.getContent()); + let enteringContent = new Animation(enteringItem.getContent()); // create animation for the entering toolbars - let enteringToolbars = new Animation(this.enteringItem.getToolbars()); + let enteringToolbars = new Animation(enteringItem.getToolbars()); // create animation for the entering title element - let enteringTitle = new Animation(this.enteringItem.getTitle()); + let enteringTitle = new Animation(enteringItem.getTitle()); // create animation for the leaving content // leavingItem could be null, but the animation instance knows to do nothing - let leavingContent = new Animation(this.leavingItem && this.leavingItem.getContent()); + let leavingContent = new Animation(leavingItem && leavingItem.getContent()); // create animation for the leaving content // leavingItem could be null, but the animation instance knows to do nothing - let leavingToolbars = new Animation(this.leavingItem && this.leavingItem.getToolbars()); + let leavingToolbars = new Animation(leavingItem && leavingItem.getToolbars()); // create animation for the entering title element - let leavingTitle = new Animation(this.leavingItem && this.leavingItem.getTitle()); + let leavingTitle = new Animation(leavingItem && leavingItem.getTitle()); // entering item moves to center // before starting, set enteringItem to display: block @@ -64,6 +65,13 @@ class IOSTransition extends Animation { enteringToolbars .beforePlay.addClass(SHOW_TOOLBAR_CSS); + // if the back button should show, then fade it in + if (enteringItem.enableBack) { + let enteringBackButton = new Animation(enteringItem.getBackButton()) + enteringBackButton.from(OPACITY, 0).to(OPACITY, 1); + this.addChild(enteringBackButton); + } + // leaving view moves off screen // when completed, set leavingItem to display: none leavingContent @@ -78,6 +86,12 @@ class IOSTransition extends Animation { .from(TRANSFORM, CENTER) .from(OPACITY, 1); + if (leavingItem && leavingItem.enableBack) { + let leavingBackButton = new Animation(leavingItem.getBackButton()) + leavingBackButton.from(OPACITY, 1).to(OPACITY, 0); + this.addChild(leavingBackButton); + } + // set properties depending on direction if (opts.direction === 'back') { // back direction diff --git a/ionic/util/util.js b/ionic/util/util.js index d80ed06b59..3cbd67504d 100644 --- a/ionic/util/util.js +++ b/ionic/util/util.js @@ -73,6 +73,7 @@ export const isNumber = val => typeof val === 'number'; export const isFunction = val => typeof val === 'function'; export const isDefined = val => typeof val !== 'undefined'; export const isUndefined = val => typeof val === 'undefined'; +export const isBlank = val => val === undefined || val === null; export const isObject = val => typeof val === 'object'; export const isArray = Array.isArray;