diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b83d833be..b9ac72d5b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,36 @@ + +# 2.0.0-beta.0 + +Enjoy! + +<3 The Ionic Team + + + + +# [2.0.0-alpha.57](https://github.com/driftyco/ionic/compare/v2.0.0-alpha.56...v2.0.0-alpha.57) (2016-02-10) + + +### Bug Fixes + +* **button:** bar-button uses inner span as flexbox ([38a3be4](https://github.com/driftyco/ionic/commit/38a3be4)) + +### Features + +* Improved transitions and animations +* hairlines width can be configured with a sass variable ([06b3a5b](https://github.com/driftyco/ionic/commit/06b3a5b)) +* **ion-item-sliding:** style icons on top of text in an option button ([4e57fcf](https://github.com/driftyco/ionic/commit/4e57fcf)), closes [#5352](https://github.com/driftyco/ionic/issues/5352) + +### Refactor + +* **animations:** no longer using Web Animations polyfill ([da18868](https://github.com/driftyco/ionic/commit/da18868)) + +### Breaking Changes + +The Web Animations polyfill is no longer shipped with the framework and may cause build errors. + +Projects will need to be [updated accordingly](https://github.com/driftyco/ionic-conference-app/commit/2ed59e6fd275c4616792c7b2e5aa9da4a20fb188). + # [2.0.0-alpha.56](https://github.com/driftyco/ionic/compare/v2.0.0-alpha.55...v2.0.0-alpha.56) (2016-02-05) diff --git a/README.md b/README.md index eb30dde795..3bc3426ac3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) -# Ionic 2: Alpha +# Ionic 2: Beta Ionic 2 is the next generation of [Ionic](http://ionicframework.com/), the open-source mobile app development SDK that makes it easy to build top quality mobile apps with web technologies. diff --git a/circle.yml b/circle.yml index f10432f336..60d75cf33d 100644 --- a/circle.yml +++ b/circle.yml @@ -1,3 +1,7 @@ +general: + branches: + ignore: + - ins_n_outs machine: node: version: 4.1.0 diff --git a/demos/item-sliding/main.html b/demos/item-sliding/main.html index 6b24c9f3bb..75912f3bf6 100644 --- a/demos/item-sliding/main.html +++ b/demos/item-sliding/main.html @@ -169,7 +169,7 @@ margin-top: -8px; } - .chat-sliding-demo ion-item-options button { + .chat-sliding-demo ion-item-options .button-inner { font-size: 14px; flex-direction: column; } diff --git a/gulpfile.js b/gulpfile.js index 56cbab1324..34b9b67cf9 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -238,6 +238,7 @@ gulp.task('transpile', function(){ function tsCompile(options, cacheName){ return gulp.src([ + 'typings/main.d.ts', 'ionic/**/*.ts', '!ionic/**/*.d.ts', '!ionic/components/*/test/**/*', @@ -709,7 +710,7 @@ gulp.task('prepare', function(){ //Update package.json version var packageJSON = require('./package.json'); - packageJSON.version = semver.inc(packageJSON.version, 'prerelease', 'alpha'); + packageJSON.version = semver.inc(packageJSON.version, 'prerelease', 'beta'); fs.writeFileSync('package.json', JSON.stringify(packageJSON, null, 2)); //Update changelog diff --git a/ionic/animations/animation.ts b/ionic/animations/animation.ts index f09d6df4cb..79268caf99 100644 --- a/ionic/animations/animation.ts +++ b/ionic/animations/animation.ts @@ -1,6 +1,5 @@ -import {ViewController} from '../components/nav/view-controller'; import {CSS, rafFrames, raf, transitionEnd} from '../util/dom'; -import {assign} from '../util/util'; +import {assign, isDefined} from '../util/util'; /** @@ -25,12 +24,14 @@ export class Animation { private _fOnceFns: Array; private _wChg: boolean = false; private _rv: boolean; + private _unregTrans: Function; + private _tmr; public isPlaying: boolean; public hasTween: boolean; public meta; - constructor(ele?, opts={}) { + constructor(ele?, opts: AnimationOptions = {}) { this._reset(); this.element(ele); @@ -54,6 +55,8 @@ export class Animation { this._fFns = []; this._fOnceFns = []; + this._clearAsync(); + this.isPlaying = this.hasTween = this._rv = false; this._el = this._easing = this._dur = null; } @@ -106,11 +109,11 @@ export class Animation { return this; } - from(prop: string, val: string): Animation { + from(prop: string, val): Animation { return this._addProp('from', prop, val); } - to(prop: string, val: string): Animation { + to(prop: string, val): Animation { return this._addProp('to', prop, val); } @@ -196,12 +199,12 @@ export class Animation { } } - play() { + play(opts: PlayOptions = {}) { var self = this; + var i; + var duration = isDefined(opts.duration) ? opts.duration : self._dur; - var i, fallbackTimerId, deregTransEnd; - - console.debug('Animation, play, duration', self._dur, 'easing', self._easing); + console.debug('Animation, play, duration', duration, 'easing', self._easing); // always default that an animation does not tween // a tween requires that an Animation class has an element @@ -226,7 +229,10 @@ export class Animation { // will recursively stage all child elements self._before(); - if (self._dur > 30) { + // ensure all past transition end events have been cleared + this._clearAsync(); + + if (duration > 30) { // this animation has a duration, so it should animate // place all the elements with their FROM properties @@ -235,9 +241,9 @@ export class Animation { self._willChange(true); - // set the TRANSITION END event + // set the async TRANSITION END event // and run onFinishes when the transition ends - self._asyncEnd(self._dur); + self._asyncEnd(duration, true); // begin each animation when everything is rendered in their place // and the transition duration/easing is ready to go @@ -245,7 +251,7 @@ export class Animation { // there's been a moment and the elements are in place // now set the TRANSITION duration/easing - self._setTrans(self._dur, false); + self._setTrans(duration, false); // wait a few moments again to wait for the transition // info to take hold in the DOM @@ -264,47 +270,73 @@ export class Animation { // just go straight to the TO properties and call it done self._progress(1); - // so there was no animation, immediately run the after + // since there was no animation, immediately run the after self._after(); - // so there was no animation, it's done + // since there was no animation, it's done // fire off all the onFinishes - self._onFinish(); + self._onFinish(true); } } - _asyncEnd(duration: number) { + stop(opts: PlayOptions = {}) { var self = this; - var deregTransEnd, fallbackTimerId; + var duration = isDefined(opts.duration) ? opts.duration : 0; + var stepValue = isDefined(opts.stepValue) ? opts.stepValue : 1; - // set the TRANSITION END event - deregTransEnd = transitionEnd(self._transEl(), function() { - // transition has completed - console.debug('Animation, transition end'); + // ensure all past transition end events have been cleared + this._clearAsync(); - // cancel the fallback timer so it doesn't fire also - clearTimeout(fallbackTimerId); + // set the TO properties + self._progress(stepValue); + + if (duration > 30) { + // this animation has a duration, so it should animate + // place all the elements with their TO properties + + // now set the TRANSITION duration + self._setTrans(duration, true); + + // set the async TRANSITION END event + // and run onFinishes when the transition ends + self._asyncEnd(duration, false); + + } else { + // this animation does not have a duration, so it should not animate + // just go straight to the TO properties and call it done + self._after(); + + // since there was no animation, it's done + // fire off all the onFinishes + self._onFinish(false); + } + } + + _asyncEnd(duration: number, shouldComplete: boolean) { + var self = this; + + function onTransitionEnd(ev) { + console.debug('Animation async end,', (ev ? 'transitionEnd, ' + ev.target.nodeName + ', property: ' + ev.propertyName : 'fallback timeout')); + + // ensure transition end events and timeouts have been cleared + self._clearAsync(); // set the after styles self._after(); self._willChange(false); - self._onFinish(); - }); + self._onFinish(shouldComplete); + } + + // set the TRANSITION END event on one of the transition elements + self._unregTrans = transitionEnd(self._transEl(), onTransitionEnd); // set a fallback timeout if the transition end event never fires - fallbackTimerId = setTimeout(function() { - // fallback timeout fired instead of the transition end - console.debug('Animation, fallback end'); + self._tmr = setTimeout(onTransitionEnd, duration + 300); + } - // deregister the transition end event listener - deregTransEnd(); - - // set the after styles - self._after(); - self._willChange(false); - self._onFinish(); - - }, duration + 300); + _clearAsync() { + this._unregTrans && this._unregTrans(); + clearTimeout(this._tmr); } _progress(stepValue: number) { @@ -548,12 +580,12 @@ export class Animation { // for example, the left menu was dragged all the way open already this._after(); this._willChange(false); - this._onFinish(); + this._onFinish(shouldComplete); } else { // the stepValue was left off at a point when it needs to finish transition still // for example, the left menu was opened 75% and needs to finish opening - this._asyncEnd(64); + this._asyncEnd(64, shouldComplete); // force quick duration, linear easing this._setTrans(64, true); @@ -565,7 +597,11 @@ export class Animation { return this; } - onFinish(callback: Function, onceTimeCallback: boolean = false) { + onFinish(callback: Function, onceTimeCallback: boolean = false, clearOnFinishCallacks: boolean = false) { + if (clearOnFinishCallacks) { + this._fFns = []; + this._fOnceFns = []; + } if (onceTimeCallback) { this._fOnceFns.push(callback); @@ -575,15 +611,15 @@ export class Animation { return this; } - _onFinish() { + _onFinish(hasCompleted: boolean) { this.isPlaying = false; var i; for (i = 0; i < this._fFns.length; i++) { - this._fFns[i](); + this._fFns[i](hasCompleted); } for (i = 0; i < this._fOnceFns.length; i++) { - this._fOnceFns[i](); + this._fOnceFns[i](hasCompleted); } this._fOnceFns = []; } @@ -625,7 +661,7 @@ export class Animation { /* STATIC CLASSES */ - static create(name: string): Animation { + static create(name: string, opts: AnimationOptions = {}): Animation { let AnimationClass = AnimationRegistry[name]; if (!AnimationClass) { @@ -633,17 +669,7 @@ export class Animation { // fallback to just the base Animation class AnimationClass = Animation; } - return new AnimationClass(); - } - - static createTransition(enteringView: ViewController, leavingView: ViewController, opts: any = {}): Animation { - let TransitionClass = AnimationRegistry[opts.animation]; - if (!TransitionClass) { - // didn't find a transition animation, default to ios-transition - TransitionClass = AnimationRegistry['ios-transition']; - } - - return new TransitionClass(enteringView, leavingView, opts); + return new AnimationClass(null, opts); } static register(name: string, AnimationClass) { @@ -652,6 +678,16 @@ export class Animation { } +export interface AnimationOptions { + animation?: string; + renderDelay?: number; +} + +export interface PlayOptions { + duration?: number; + stepValue?: number; +} + const doc: any = document; const TRANSFORMS = [ 'translateX', 'translateY', 'translateZ', 'scale', 'scaleX', 'scaleY', 'scaleZ', diff --git a/ionic/components/action-sheet/action-sheet.ts b/ionic/components/action-sheet/action-sheet.ts index c6cc230aa4..ede74cfb9f 100644 --- a/ionic/components/action-sheet/action-sheet.ts +++ b/ionic/components/action-sheet/action-sheet.ts @@ -2,6 +2,7 @@ import {Component, Renderer, ElementRef} from 'angular2/core'; import {NgFor, NgIf} from 'angular2/common'; import {Animation} from '../../animations/animation'; +import {Transition, TransitionOptions} from '../../transitions/transition'; import {Config} from '../../config/config'; import {Icon} from '../icon/icon'; import {isDefined} from '../../util/util'; @@ -129,7 +130,8 @@ import {ViewController} from '../nav/view-controller'; title?: string, subTitle?: string, cssClass?: string, - buttons?: Array + buttons?: Array, + enableBackdropDismiss?: boolean } = {}) { return new ActionSheet(opts); } @@ -272,9 +274,9 @@ class ActionSheetCmp { -class ActionSheetSlideIn extends Animation { - constructor(enteringView, leavingView, opts) { - super(null, opts); +class ActionSheetSlideIn extends Transition { + constructor(enteringView, leavingView, opts: TransitionOptions) { + super(opts); let ele = enteringView.pageRef().nativeElement; let backdrop = new Animation(ele.querySelector('.backdrop')); @@ -286,12 +288,12 @@ class ActionSheetSlideIn extends Animation { this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add(backdrop).add(wrapper); } } -Animation.register('action-sheet-slide-in', ActionSheetSlideIn); +Transition.register('action-sheet-slide-in', ActionSheetSlideIn); -class ActionSheetSlideOut extends Animation { - constructor(enteringView, leavingView, opts) { - super(null, opts); +class ActionSheetSlideOut extends Transition { + constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) { + super(opts); let ele = leavingView.pageRef().nativeElement; let backdrop = new Animation(ele.querySelector('.backdrop')); @@ -303,12 +305,12 @@ class ActionSheetSlideOut extends Animation { this.easing('cubic-bezier(.36,.66,.04,1)').duration(300).add(backdrop).add(wrapper); } } -Animation.register('action-sheet-slide-out', ActionSheetSlideOut); +Transition.register('action-sheet-slide-out', ActionSheetSlideOut); -class ActionSheetMdSlideIn extends Animation { - constructor(enteringView, leavingView, opts) { - super(null, opts); +class ActionSheetMdSlideIn extends Transition { + constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) { + super(opts); let ele = enteringView.pageRef().nativeElement; let backdrop = new Animation(ele.querySelector('.backdrop')); @@ -320,12 +322,12 @@ class ActionSheetMdSlideIn extends Animation { this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add(backdrop).add(wrapper); } } -Animation.register('action-sheet-md-slide-in', ActionSheetMdSlideIn); +Transition.register('action-sheet-md-slide-in', ActionSheetMdSlideIn); -class ActionSheetMdSlideOut extends Animation { - constructor(enteringView, leavingView, opts) { - super(null, opts); +class ActionSheetMdSlideOut extends Transition { + constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) { + super(opts); let ele = leavingView.pageRef().nativeElement; let backdrop = new Animation(ele.querySelector('.backdrop')); @@ -337,4 +339,4 @@ class ActionSheetMdSlideOut extends Animation { this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add(backdrop).add(wrapper); } } -Animation.register('action-sheet-md-slide-out', ActionSheetMdSlideOut); +Transition.register('action-sheet-md-slide-out', ActionSheetMdSlideOut); diff --git a/ionic/components/action-sheet/test/basic/index.ts b/ionic/components/action-sheet/test/basic/index.ts index 0c86f08c4b..134d6258f1 100644 --- a/ionic/components/action-sheet/test/basic/index.ts +++ b/ionic/components/action-sheet/test/basic/index.ts @@ -1,4 +1,4 @@ -import {App, Page, ActionSheet, NavController} from 'ionic/ionic'; +import {App, Page, ActionSheet, NavController} from '../../../../../ionic/ionic'; @Page({ diff --git a/ionic/components/alert/alert.ios.scss b/ionic/components/alert/alert.ios.scss index dae533819f..8bcc25f114 100644 --- a/ionic/components/alert/alert.ios.scss +++ b/ionic/components/alert/alert.ios.scss @@ -94,6 +94,12 @@ ion-alert { text-align: $alert-ios-message-text-align; } +.alert-message { + &:empty { + padding: 0 0 12px 0; + } +} + // iOS Alert Input // -------------------------------------------------- diff --git a/ionic/components/alert/alert.md.scss b/ionic/components/alert/alert.md.scss index 9661389f6a..7d6c966c36 100644 --- a/ionic/components/alert/alert.md.scss +++ b/ionic/components/alert/alert.md.scss @@ -1,5 +1,6 @@ @import "../../globals.md"; @import "./alert"; +@import "../button/button.md"; // Material Design Alerts // -------------------------------------------------- @@ -68,6 +69,10 @@ $alert-md-buttons-justify-content: flex-end !default; .alert-message { font-size: $alert-md-message-font-size; + + &:empty { + padding: 0; + } } @@ -226,6 +231,7 @@ $alert-md-buttons-justify-content: flex-end !default; text-align: right; &.activated { + background-color: $button-md-clear-active-background-color; opacity: 1; } } diff --git a/ionic/components/alert/alert.scss b/ionic/components/alert/alert.scss index a1364e3441..b43c4c5d98 100644 --- a/ionic/components/alert/alert.scss +++ b/ionic/components/alert/alert.scss @@ -52,10 +52,6 @@ ion-alert { .alert-message { overflow: auto; - - &:empty { - padding: 0; - } } .alert-input { diff --git a/ionic/components/alert/alert.ts b/ionic/components/alert/alert.ts index 3874a8e823..3f56addfc7 100644 --- a/ionic/components/alert/alert.ts +++ b/ionic/components/alert/alert.ts @@ -2,6 +2,7 @@ import {Component, ElementRef, Renderer} from 'angular2/core'; import {NgClass, NgSwitch, NgIf, NgFor} from 'angular2/common'; import {Animation} from '../../animations/animation'; +import {Transition, TransitionOptions} from '../../transitions/transition'; import {Config} from '../../config/config'; import {isDefined} from '../../util/util'; import {NavParams} from '../nav/nav-params'; @@ -197,7 +198,7 @@ export class Alert extends ViewController { } /** - * @param {object} button Alert button + * @param {any} button Alert button */ addButton(button: any) { this.data.buttons.push(button); @@ -211,7 +212,7 @@ export class Alert extends ViewController { } /** - * @param {Object} opts Alert options + * @param {object} opts Alert options */ static create(opts: { title?: string, @@ -247,7 +248,7 @@ export class Alert extends ViewController { '

' + '

' + '' + - '
' + + '
' + '
' + '