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 @@
[](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 {
' ' +
' ' +
'' +
- '
' +
+ '
' +
'' +
'' +
@@ -334,6 +335,10 @@ class AlertCmp {
} else if (this.d.subTitle) {
this.descId = this.subHdrId;
}
+
+ if (!this.d.message) {
+ this.d.message = '';
+ }
}
onPageLoaded() {
@@ -484,9 +489,9 @@ class AlertCmp {
/**
* Animations for alerts
*/
-class AlertPopIn extends Animation {
- constructor(enteringView, leavingView, opts) {
- super(null, opts);
+class AlertPopIn extends Transition {
+ constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
+ super(opts);
let ele = enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('.backdrop'));
@@ -502,12 +507,12 @@ class AlertPopIn extends Animation {
.add(wrapper);
}
}
-Animation.register('alert-pop-in', AlertPopIn);
+Transition.register('alert-pop-in', AlertPopIn);
-class AlertPopOut extends Animation {
- constructor(enteringView, leavingView, opts) {
- super(null, opts);
+class AlertPopOut extends Transition {
+ constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
+ super(opts);
let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('.backdrop'));
@@ -523,12 +528,12 @@ class AlertPopOut extends Animation {
.add(wrapper);
}
}
-Animation.register('alert-pop-out', AlertPopOut);
+Transition.register('alert-pop-out', AlertPopOut);
-class AlertMdPopIn extends Animation {
- constructor(enteringView, leavingView, opts) {
- super(null, opts);
+class AlertMdPopIn extends Transition {
+ constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
+ super(opts);
let ele = enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('.backdrop'));
@@ -544,12 +549,12 @@ class AlertMdPopIn extends Animation {
.add(wrapper);
}
}
-Animation.register('alert-md-pop-in', AlertMdPopIn);
+Transition.register('alert-md-pop-in', AlertMdPopIn);
-class AlertMdPopOut extends Animation {
- constructor(enteringView, leavingView, opts) {
- super(null, opts);
+class AlertMdPopOut extends Transition {
+ constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
+ super(opts);
let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('.backdrop'));
@@ -565,6 +570,6 @@ class AlertMdPopOut extends Animation {
.add(wrapper);
}
}
-Animation.register('alert-md-pop-out', AlertMdPopOut);
+Transition.register('alert-md-pop-out', AlertMdPopOut);
let alertIds = -1;
diff --git a/ionic/components/alert/test/basic/index.ts b/ionic/components/alert/test/basic/index.ts
index b3117960e5..268592ebf3 100644
--- a/ionic/components/alert/test/basic/index.ts
+++ b/ionic/components/alert/test/basic/index.ts
@@ -1,17 +1,16 @@
-import {App, Page, Alert, NavController} from 'ionic/ionic';
+import {App, Page, Alert, NavController} from '../../../../../ionic/ionic';
@Page({
templateUrl: 'main.html'
})
class E2EPage {
+ testConfirmOpen: boolean = false;
+ testPromptOpen: boolean = false;
+ testConfirmResult: string = '';
+ testPromptResult: string = '';
- constructor(private nav: NavController) {
- this.testConfirmOpen = false;
- this.testPromptOpen = false;
- this.testConfirmResult = '';
- this.testPromptResult = '';
- }
+ constructor(private nav: NavController) { }
doAlert() {
let alert = Alert.create({
@@ -60,6 +59,14 @@ class E2EPage {
this.nav.present(alert);
}
+ doAlertNoMessage() {
+ let alert = Alert.create({
+ title: 'Alert',
+ buttons: ['OK']
+ });
+ this.nav.present(alert);
+ }
+
doMultipleButtons() {
let alert = Alert.create({
title: 'Alert',
@@ -234,7 +241,7 @@ class E2EPage {
setTimeout(() => {
alert.dismiss();
- }, 100);
+ }, 200);
}
doDisabledBackdropAlert() {
diff --git a/ionic/components/alert/test/basic/main.html b/ionic/components/alert/test/basic/main.html
index 505b450b42..3aa69d47c2 100644
--- a/ionic/components/alert/test/basic/main.html
+++ b/ionic/components/alert/test/basic/main.html
@@ -7,6 +7,7 @@
Alert
Alert Long Message
Multiple Buttons (>2)
+ Alert No Message
Confirm
Prompt
Radio
diff --git a/ionic/components/app/app.ts b/ionic/components/app/app.ts
index cf8864e743..e5c612c21c 100644
--- a/ionic/components/app/app.ts
+++ b/ionic/components/app/app.ts
@@ -50,8 +50,8 @@ export class IonicApp {
* available to accept new user commands. For example, this is set to `false`
* while views transition, a modal slides up, an action-sheet
* slides up, etc. After the transition completes it is set back to `true`.
- * @param {bool} isEnabled
- * @param {bool} fallback When `isEnabled` is set to `false`, this argument
+ * @param {boolean} isEnabled
+ * @param {boolean} fallback When `isEnabled` is set to `false`, this argument
* is used to set the maximum number of milliseconds that app will wait until
* it will automatically enable the app again. It's basically a fallback incase
* something goes wrong during a transition and the app wasn't re-enabled correctly.
@@ -68,7 +68,7 @@ export class IonicApp {
/**
* @private
* Boolean if the app is actively enabled or not.
- * @return {bool}
+ * @return {boolean}
*/
isEnabled(): boolean {
return (this._disTime < Date.now());
@@ -84,7 +84,7 @@ export class IonicApp {
/**
* @private
* Boolean if the app is actively scrolling or not.
- * @return {bool}
+ * @return {boolean}
*/
isScrolling(): boolean {
return (this._scrollTime + 64 > Date.now());
@@ -94,7 +94,7 @@ export class IonicApp {
* @private
* Register a known component with a key, for easy lookups later.
* @param {string} id The id to use to register the component
- * @param {Object} component The component to register
+ * @param {object} component The component to register
*/
register(id: string, component: any) {
this.components[id] = component;
@@ -112,8 +112,8 @@ export class IonicApp {
/**
* @private
* Get a registered component with the given type (returns the first)
- * @param {Object} cls the type to search for
- * @return {Object} the matching component, or undefined if none was found
+ * @param {object} cls the type to search for
+ * @return {object} the matching component, or undefined if none was found
*/
getRegisteredComponent(cls: any): any {
for (let key in this.components) {
@@ -128,7 +128,7 @@ export class IonicApp {
* @private
* Get the component for the given key.
* @param {string} id TODO
- * @return {Object} TODO
+ * @return {object} TODO
*/
getComponent(id: string): any {
// deprecated warning
diff --git a/ionic/components/app/id.ts b/ionic/components/app/id.ts
index cca91f0c97..800895c127 100644
--- a/ionic/components/app/id.ts
+++ b/ionic/components/app/id.ts
@@ -18,7 +18,7 @@ import {IonicApp} from './app';
*
* ```
*
- * To get a reference to the registered component, inject the [IonicApp](../app/IonicApp/)
+ * To get a reference to the registered component, inject the [IonicApp](../IonicApp/)
* service:
* ```ts
* constructor(app: IonicApp) {
diff --git a/ionic/components/app/test/animations/index.ts b/ionic/components/app/test/animations/index.ts
index 0cd0ff07ff..28e529ad7b 100644
--- a/ionic/components/app/test/animations/index.ts
+++ b/ionic/components/app/test/animations/index.ts
@@ -1,4 +1,4 @@
-import {App, Page, Animation} from 'ionic/ionic';
+import {App, Page, Animation} from '../../../../../ionic/ionic';
@Page({
diff --git a/ionic/components/app/test/storage/index.ts b/ionic/components/app/test/storage/index.ts
index 0c60345a83..ad60d39f86 100644
--- a/ionic/components/app/test/storage/index.ts
+++ b/ionic/components/app/test/storage/index.ts
@@ -1,7 +1,7 @@
import {Component} from 'angular2/core';
import {Control, ControlGroup} from 'angular2/common';
-import {App, Storage, LocalStorage, SqlStorage} from 'ionic/ionic';
+import {App, Storage, LocalStorage, SqlStorage} from '../../../../../ionic/ionic';
@App({
templateUrl: 'main.html'
diff --git a/ionic/components/app/test/typography/index.ts b/ionic/components/app/test/typography/index.ts
index ff6f299c59..c77689fd38 100644
--- a/ionic/components/app/test/typography/index.ts
+++ b/ionic/components/app/test/typography/index.ts
@@ -1,4 +1,4 @@
-import {App, IonicApp} from 'ionic/ionic';
+import {App, IonicApp} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/badge/test/basic/index.ts b/ionic/components/badge/test/basic/index.ts
index 2dd534c468..b4a0c315f8 100644
--- a/ionic/components/badge/test/basic/index.ts
+++ b/ionic/components/badge/test/basic/index.ts
@@ -1,4 +1,4 @@
-import {App, IonicApp} from 'ionic/ionic';
+import {App, IonicApp} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/blur/test/basic/index.ts b/ionic/components/blur/test/basic/index.ts
index ac2d757460..bc32179fee 100644
--- a/ionic/components/blur/test/basic/index.ts
+++ b/ionic/components/blur/test/basic/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/button/button.ios.scss b/ionic/components/button/button.ios.scss
index e4bb68342e..2c1fe9381c 100644
--- a/ionic/components/button/button.ios.scss
+++ b/ionic/components/button/button.ios.scss
@@ -97,7 +97,6 @@ $button-ios-small-icon-font-size: 1.3em !default;
margin-right: 0;
}
-
// iOS Full Button
// --------------------------------------------------
@@ -105,11 +104,10 @@ $button-ios-small-icon-font-size: 1.3em !default;
margin-right: 0;
margin-left: 0;
border-radius: 0;
- border-left: none;
- border-right: none;
+ border-right-width: 0;
+ border-left-width: 0;
}
-
// iOS Outline Button
// --------------------------------------------------
diff --git a/ionic/components/button/button.md.scss b/ionic/components/button/button.md.scss
index 5b34f4e215..18cc26ed72 100644
--- a/ionic/components/button/button.md.scss
+++ b/ionic/components/button/button.md.scss
@@ -58,7 +58,7 @@ $button-md-small-icon-font-size: 1.4em !default;
color $button-md-transition-duration $button-md-animation-curve;
&:hover:not(.disable-hover) {
- background-color: $button-md-clear-hover-background-color;
+ background-color: $button-md-color;
}
&.activated {
@@ -85,6 +85,10 @@ $button-md-small-icon-font-size: 1.4em !default;
color: $fg-color;
background-color: $bg-color;
+ &:hover:not(.disable-hover) {
+ background-color: $bg-color;
+ }
+
&.activated {
opacity: 1;
background-color: $bg-color-activated;
@@ -117,28 +121,25 @@ $button-md-small-icon-font-size: 1.4em !default;
font-size: $button-md-small-icon-font-size;
}
+// Material Design Block Button
+// --------------------------------------------------
+
+.button-block {
+ margin-left: 0;
+ margin-right: 0;
+}
// Material Design Full Button
// --------------------------------------------------
.button-full {
- border-radius: 0;
margin-right: 0;
margin-left: 0;
+ border-radius: 0;
border-right-width: 0;
border-left-width: 0;
}
-
-// Material Design Block Button
-// --------------------------------------------------
-
-.button-block {
- margin-right: 0;
- margin-left: 0;
-}
-
-
// Material Design Outline Button
// --------------------------------------------------
@@ -150,6 +151,10 @@ $button-md-small-icon-font-size: 1.4em !default;
color: $button-md-color;
box-shadow: none;
+ &:hover:not(.disable-hover) {
+ background-color: $button-md-clear-hover-background-color;
+ }
+
&.activated {
opacity: 1;
box-shadow: none;
@@ -173,6 +178,10 @@ $button-md-small-icon-font-size: 1.4em !default;
background-color: transparent;
color: $fg-color;
+ &:hover:not(.disable-hover) {
+ background-color: $button-md-clear-hover-background-color;
+ }
+
&.activated {
background-color: transparent;
}
@@ -201,7 +210,7 @@ $button-md-small-icon-font-size: 1.4em !default;
}
&:hover:not(.disable-hover) {
- color: $button-md-color;
+ background-color: $button-md-clear-hover-background-color;
}
ion-button-effect {
diff --git a/ionic/components/button/button.scss b/ionic/components/button/button.scss
index 3b26fc0234..ac4eeaf672 100644
--- a/ionic/components/button/button.scss
+++ b/ionic/components/button/button.scss
@@ -29,17 +29,17 @@ $button-round-border-radius: 64px !default;
@include appearance(none);
}
-span.button-inner {
- width: 100%;
- height: 100%;
- display: flex;
- flex-shrink: 0;
- flex-flow: row nowrap;
- align-items: center;
- justify-content: center;
+.button-inner {
+ display: flex;
+ flex-shrink: 0;
+ flex-flow: row nowrap;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 100%;
}
-a.button {
+a.button, a[button] {
text-decoration: none;
}
@@ -54,7 +54,7 @@ a.button {
// --------------------------------------------------
.button-block {
- display: flex;
+ display: block;
clear: both;
width: 100%;
@@ -68,6 +68,7 @@ a.button {
// --------------------------------------------------
.button-full {
+ display: block;
width: 100%;
}
diff --git a/ionic/components/button/test/basic/index.ts b/ionic/components/button/test/basic/index.ts
index 01b30a6221..0619a93f8d 100644
--- a/ionic/components/button/test/basic/index.ts
+++ b/ionic/components/button/test/basic/index.ts
@@ -1,4 +1,4 @@
-import {App, IonicApp} from 'ionic/ionic';
+import {App, IonicApp} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/button/test/block/index.ts b/ionic/components/button/test/block/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/button/test/block/index.ts
+++ b/ionic/components/button/test/block/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/button/test/button.spec.ts b/ionic/components/button/test/button.spec.ts
index a7c17093ca..2a84e7f6cb 100644
--- a/ionic/components/button/test/button.spec.ts
+++ b/ionic/components/button/test/button.spec.ts
@@ -1,4 +1,4 @@
-import {Button, Config} from 'ionic/ionic';
+import {Button, Config} from '../../../../ionic/ionic';
export function run() {
diff --git a/ionic/components/button/test/clear/index.ts b/ionic/components/button/test/clear/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/button/test/clear/index.ts
+++ b/ionic/components/button/test/clear/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/button/test/fab/index.ts b/ionic/components/button/test/fab/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/button/test/fab/index.ts
+++ b/ionic/components/button/test/fab/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/button/test/full/index.ts b/ionic/components/button/test/full/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/button/test/full/index.ts
+++ b/ionic/components/button/test/full/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/button/test/icons/index.ts b/ionic/components/button/test/icons/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/button/test/icons/index.ts
+++ b/ionic/components/button/test/icons/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/button/test/outline/index.ts b/ionic/components/button/test/outline/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/button/test/outline/index.ts
+++ b/ionic/components/button/test/outline/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/button/test/round/index.ts b/ionic/components/button/test/round/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/button/test/round/index.ts
+++ b/ionic/components/button/test/round/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/button/test/sizes/index.ts b/ionic/components/button/test/sizes/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/button/test/sizes/index.ts
+++ b/ionic/components/button/test/sizes/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/card/card.ios.scss b/ionic/components/card/card.ios.scss
index 68209993f5..965e76618b 100644
--- a/ionic/components/card/card.ios.scss
+++ b/ionic/components/card/card.ios.scss
@@ -25,6 +25,7 @@ $card-ios-font-size: 1.4rem !default;
$card-ios-text-color: #666 !default;
$card-ios-title-font-size: 1.8rem !default;
$card-ios-title-padding: 8px 0 8px 0 !default;
+$card-ios-title-margin: 2px 0 2px !default;
$card-ios-title-text-color: #222 !default;
$card-ios-header-font-size: 1.6rem !default;
@@ -85,8 +86,11 @@ ion-card {
font-size: 1.3rem;
}
- .card-title {
+ ion-card-title {
+ display: block;
+ line-height: 1.2;
padding: $card-ios-title-padding;
+ margin: $card-ios-title-margin;
font-size: $card-ios-title-font-size;
color: $card-ios-title-text-color;
}
diff --git a/ionic/components/card/card.md.scss b/ionic/components/card/card.md.scss
index 35df38e784..195a9d8632 100644
--- a/ionic/components/card/card.md.scss
+++ b/ionic/components/card/card.md.scss
@@ -29,6 +29,7 @@ $card-md-line-height: 1.5 !default;
$card-md-text-color: #222 !default;
$card-md-title-font-size: 2.4rem !default;
$card-md-title-padding: 8px 0 8px 0 !default;
+$card-md-title-margin: 2px 0 2px !default;
$card-md-title-text-color: #222 !default;
$card-md-header-font-size: 1.6rem !default;
@@ -87,8 +88,11 @@ ion-card {
font-size: 1.3rem;
}
- .card-title {
+ ion-card-title {
+ display: block;
+ line-height: 1.2;
padding: $card-md-title-padding;
+ margin: $card-md-title-margin;
font-size: $card-md-title-font-size;
color: $card-md-title-text-color;
}
diff --git a/ionic/components/card/test/advanced/index.ts b/ionic/components/card/test/advanced/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/card/test/advanced/index.ts
+++ b/ionic/components/card/test/advanced/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/card/test/advanced/main.html b/ionic/components/card/test/advanced/main.html
index f8d0adc594..6cee3f5fa8 100644
--- a/ionic/components/card/test/advanced/main.html
+++ b/ionic/components/card/test/advanced/main.html
@@ -10,9 +10,9 @@
-
+
Card Title Goes Here
-
+
Keep close to Nature's heart... and break clear away,
once in awhile, and climb a mountain. I am within a paragraph element.
diff --git a/ionic/components/card/test/basic/index.ts b/ionic/components/card/test/basic/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/card/test/basic/index.ts
+++ b/ionic/components/card/test/basic/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/card/test/images/index.ts b/ionic/components/card/test/images/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/card/test/images/index.ts
+++ b/ionic/components/card/test/images/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/card/test/list/index.ts b/ionic/components/card/test/list/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/card/test/list/index.ts
+++ b/ionic/components/card/test/list/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/card/test/map/index.ts b/ionic/components/card/test/map/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/card/test/map/index.ts
+++ b/ionic/components/card/test/map/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/card/test/map/main.html b/ionic/components/card/test/map/main.html
index 96572af045..51b6fcb4a5 100644
--- a/ionic/components/card/test/map/main.html
+++ b/ionic/components/card/test/map/main.html
@@ -9,17 +9,17 @@
-
+
-
+
Museum of Football
11 N. Way St, Madison, WI 53703
-
+
Institute of Fine Cocktails
14 S. Hop Avenue, Madison, WI 53703
@@ -28,7 +28,7 @@
18 min
(2.6 mi)
-
+
Start
@@ -39,17 +39,17 @@
-
+
-
+
Yoshi's Island
Iggy Koopa
-
+
Forest of Illusion
Roy Koopa
@@ -58,7 +58,7 @@
3 hr
(4.8 mi)
-
+
Start
@@ -69,17 +69,17 @@
-
+
-
+
Museum of Information
44 Rue de Info, 75010 Paris, France
-
+
General Pharmacy
1 Avenue Faux, 75010 Paris, France
@@ -88,7 +88,7 @@
26 min
(8.1 mi)
-
+
Start
diff --git a/ionic/components/card/test/social/index.ts b/ionic/components/card/test/social/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/card/test/social/index.ts
+++ b/ionic/components/card/test/social/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/card/test/social/main.html b/ionic/components/card/test/social/main.html
index 5486f8df90..7175493542 100644
--- a/ionic/components/card/test/social/main.html
+++ b/ionic/components/card/test/social/main.html
@@ -23,11 +23,11 @@
-
+
12 Likes
-
+
4 Comments
@@ -56,11 +56,11 @@
-
+
30 Likes
-
+
64 Comments
@@ -88,11 +88,11 @@
-
+
46 Likes
-
+
66 Comments
diff --git a/ionic/components/checkbox/checkbox.ts b/ionic/components/checkbox/checkbox.ts
index b7300d8e64..b47403a71d 100644
--- a/ionic/components/checkbox/checkbox.ts
+++ b/ionic/components/checkbox/checkbox.ts
@@ -1,20 +1,22 @@
-import {Component, Optional, Input, HostListener} from 'angular2/core';
-import {NgControl} from 'angular2/common';
+import {Component, Optional, Input, HostListener, Provider, forwardRef} from 'angular2/core';
+import {NG_VALUE_ACCESSOR} from 'angular2/common';
import {Form} from '../../util/form';
import {Item} from '../item/item';
import {isTrueProperty} from '../../util/util';
+const CHECKBOX_VALUE_ACCESSOR = new Provider(
+ NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => Checkbox), multi: true});
+
+
/**
* The checkbox is no different than the HTML checkbox input, except
* it's styled accordingly to the the platform and design mode, such
* as iOS or Material Design.
*
- * See the [Angular 2 Docs](https://angular.io/docs/js/latest/api/core/Form-interface.html) for more info on forms and input.
+ * See the [Angular 2 Docs](https://angular.io/docs/ts/latest/guide/forms.html)
+ * for more info on forms and inputs.
*
- * @property [checked] - whether or not the checkbox is checked (defaults to false)
- * @property [value] - the value of the checkbox component
- * @property [disabled] - whether or not the checkbox is disabled or not.
*
* @usage
* ```html
@@ -23,17 +25,17 @@ import {isTrueProperty} from '../../util/util';
*
*
* Pepperoni
- *
+ *
*
*
*
* Sausage
- *
+ *
*
*
*
* Mushrooms
- *
+ *
*
*
*
@@ -56,34 +58,26 @@ import {isTrueProperty} from '../../util/util';
'',
host: {
'[class.checkbox-disabled]': '_disabled'
- }
+ },
+ providers: [CHECKBOX_VALUE_ACCESSOR]
})
export class Checkbox {
private _checked: any = false;
private _disabled: any = false;
private _labelId: string;
+ private _fn: Function;
/**
* @private
*/
id: string;
- /**
- * @private
- */
- @Input() value: string = '';
-
constructor(
private _form: Form,
- @Optional() private _item: Item,
- @Optional() ngControl: NgControl
+ @Optional() private _item: Item
) {
_form.register(this);
- if (ngControl) {
- ngControl.valueAccessor = this;
- }
-
if (_item) {
this.id = 'chk-' + _item.registerInput('checkbox');
this._labelId = 'lbl-' + _item.id;
@@ -93,14 +87,17 @@ export class Checkbox {
/**
* @private
- * Toggle the checked state of the checkbox. Calls onChange to pass the updated checked state to the model (Control).
*/
- toggle() {
- this.checked = !this.checked;
+ @HostListener('click', ['$event'])
+ private _click(ev) {
+ console.debug('checkbox, checked');
+ ev.preventDefault();
+ ev.stopPropagation();
+ this.onChange(!this._checked);
}
/**
- * @private
+ * @input {boolean} whether or not the checkbox is checked (defaults to false)
*/
@Input()
get checked() {
@@ -108,22 +105,52 @@ export class Checkbox {
}
set checked(val) {
- if (!this._disabled) {
- this._checked = isTrueProperty(val);
- this.onChange(this._checked);
- this._item && this._item.setCssClass('item-checkbox-checked', this._checked);
- }
+ this._setChecked(isTrueProperty(val));
+ this.onChange(this._checked);
}
/**
* @private
*/
+ private _setChecked(isChecked: boolean) {
+ this._checked = isChecked;
+ this._item && this._item.setCssClass('item-checkbox-checked', isChecked);
+ }
+
+ /**
+ * @private
+ */
+ writeValue(val: any) {
+ this._setChecked( isTrueProperty(val) );
+ }
+
+ /**
+ * @private
+ */
+ registerOnChange(fn: Function): void {
+ this._fn = fn;
+ this.onChange = (isChecked: boolean) => {
+ console.debug('checkbox, onChange', isChecked);
+ fn(isChecked);
+ this._setChecked(isChecked);
+ this.onTouched();
+ };
+ }
+
+ /**
+ * @private
+ */
+ registerOnTouched(fn) { this.onTouched = fn; }
+
+ /**
+ * @input {boolean} whether or not the checkbox is disabled or not.
+ */
@Input()
- get disabled() {
+ get disabled(): any {
return this._disabled;
}
- set disabled(val) {
+ set disabled(val: any) {
this._disabled = isTrueProperty(val);
this._item && this._item.setCssClass('item-checkbox-disabled', this._disabled);
}
@@ -131,56 +158,12 @@ export class Checkbox {
/**
* @private
*/
- @HostListener('click', ['$event'])
- private _click(ev) {
- console.debug('checkbox, checked', this.value);
- ev.preventDefault();
- ev.stopPropagation();
- this.toggle();
- }
-
- /**
- * @private
- * Angular2 Forms API method called by the model (Control) on change to update
- * the checked value.
- * https://github.com/angular/angular/blob/master/modules/angular2/src/forms/directives/shared.ts#L34
- */
- writeValue(val) {
- if (val !== null) {
- this.checked = val;
- }
- }
+ onChange(_) {}
/**
* @private
*/
- onChange(val) {
- // TODO: figure the whys and the becauses
- }
-
- /**
- * @private
- */
- onTouched(val) {
- // TODO: figure the whys and the becauses
- }
-
- /**
- * @private
- * Angular2 Forms API method called by the view (NgControl) to register the
- * onChange event handler that updates the model (Control).
- * https://github.com/angular/angular/blob/master/modules/angular2/src/forms/directives/shared.ts#L27
- * @param {Function} fn the onChange event handler.
- */
- registerOnChange(fn) { this.onChange = fn; }
-
- /**
- * @private
- * Angular2 Forms API method called by the the view (NgControl) to register
- * the onTouched event handler that marks model (Control) as touched.
- * @param {Function} fn onTouched event handler.
- */
- registerOnTouched(fn) { this.onTouched = fn; }
+ onTouched() {}
/**
* @private
diff --git a/ionic/components/checkbox/test/basic/e2e.ts b/ionic/components/checkbox/test/basic/e2e.ts
index 5dcfccb886..93fb6898d1 100644
--- a/ionic/components/checkbox/test/basic/e2e.ts
+++ b/ionic/components/checkbox/test/basic/e2e.ts
@@ -1,6 +1,6 @@
it('should check apple, enable/check grape, submit form', function() {
- element(by.css('[ngControl=appleCtrl] button')).click();
+ element(by.css('[ngControl=appleCtrl]')).click();
element(by.css('.e2eGrapeDisabled')).click();
element(by.css('.e2eGrapeChecked')).click();
element(by.css('.e2eSubmit')).click();
diff --git a/ionic/components/checkbox/test/basic/index.ts b/ionic/components/checkbox/test/basic/index.ts
index f25c1e455d..0e0a75004a 100644
--- a/ionic/components/checkbox/test/basic/index.ts
+++ b/ionic/components/checkbox/test/basic/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
import {
Control,
ControlGroup,
@@ -16,9 +16,17 @@ import {
templateUrl: 'main.html'
})
class E2EApp {
+ fruitsForm: ControlGroup;
+ grapeDisabled: boolean;
+ grapeChecked: boolean;
+ kiwiModel: boolean;
+ strawberryModel: boolean;
+ standAloneChecked: boolean;
+ formResults: string;
+
constructor() {
this.fruitsForm = new ControlGroup({
- "appleCtrl": new Control(),
+ "appleCtrl": new Control(true),
"bananaCtrl": new Control(true),
"cherryCtrl": new Control(false),
"grapeCtrl": new Control(true)
@@ -27,6 +35,9 @@ class E2EApp {
this.grapeDisabled = true;
this.grapeChecked = true;
this.standAloneChecked = true;
+
+ this.kiwiModel = false;
+ this.strawberryModel = true;
}
toggleGrapeChecked() {
diff --git a/ionic/components/checkbox/test/basic/main.html b/ionic/components/checkbox/test/basic/main.html
index 618fad4b69..18815a3306 100644
--- a/ionic/components/checkbox/test/basic/main.html
+++ b/ionic/components/checkbox/test/basic/main.html
@@ -9,33 +9,33 @@
- Apple, value=apple, init checked
-
+ Apple, ngControl
+
- Banana, init no checked/value attributes
+ Banana, ngControl
- Cherry, value=cherry, init disabled
-
+ Cherry, ngControl, disabled
+
- Grape, value=grape, init checked, disabled
-
+ Grape, ngControl, checked, disabled
+
- secondary color
-
+ Kiwi, NgModel false, Secondary color
+
- light color
-
+ Strawberry, NgModel true
+
@@ -62,6 +62,8 @@
cherry.value: {{fruitsForm.controls.cherryCtrl.value}}
grape.dirty: {{fruitsForm.controls.grapeCtrl.dirty}}
grape.value: {{fruitsForm.controls.grapeCtrl.value}}
+ kiwiModel: {{kiwiModel}}
+ strawberryModel: {{strawberryModel}}
{{formResults}}
diff --git a/ionic/components/chip/test/basic/index.ts b/ionic/components/chip/test/basic/index.ts
index 2dd534c468..b4a0c315f8 100644
--- a/ionic/components/chip/test/basic/index.ts
+++ b/ionic/components/chip/test/basic/index.ts
@@ -1,4 +1,4 @@
-import {App, IonicApp} from 'ionic/ionic';
+import {App, IonicApp} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/chip/test/delete/index.ts b/ionic/components/chip/test/delete/index.ts
index e86f128fb0..c35cc11fbc 100644
--- a/ionic/components/chip/test/delete/index.ts
+++ b/ionic/components/chip/test/delete/index.ts
@@ -1,4 +1,4 @@
-import {App, IonicApp} from 'ionic/ionic';
+import {App, IonicApp} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/chip/test/icon/index.ts b/ionic/components/chip/test/icon/index.ts
index 2dd534c468..b4a0c315f8 100644
--- a/ionic/components/chip/test/icon/index.ts
+++ b/ionic/components/chip/test/icon/index.ts
@@ -1,4 +1,4 @@
-import {App, IonicApp} from 'ionic/ionic';
+import {App, IonicApp} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/chip/test/image/index.ts b/ionic/components/chip/test/image/index.ts
index 2dd534c468..b4a0c315f8 100644
--- a/ionic/components/chip/test/image/index.ts
+++ b/ionic/components/chip/test/image/index.ts
@@ -1,4 +1,4 @@
-import {App, IonicApp} from 'ionic/ionic';
+import {App, IonicApp} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/content/content.ts b/ionic/components/content/content.ts
index 7ed073a0f8..74b725ade1 100644
--- a/ionic/components/content/content.ts
+++ b/ionic/components/content/content.ts
@@ -43,8 +43,8 @@ export class Content extends Ion {
scrollElement: HTMLElement;
/**
- * @param {ElementRef} elementRef A reference to the component's DOM element.
- * @param {Config} config The config object to change content's default settings.
+ * @param {elementRef} elementRef A reference to the component's DOM element.
+ * @param {config} config The config object to change content's default settings.
*/
constructor(
private _elementRef: ElementRef,
@@ -87,6 +87,7 @@ export class Content extends Ion {
}
/**
+ * @private
* Adds the specified scroll handler to the content' scroll element.
*
* ```ts
@@ -224,9 +225,9 @@ export class Content extends Ion {
* }
* }
* ```
- * @param {Number} x The x-value to scroll to.
- * @param {Number} y The y-value to scroll to.
- * @param {Number} duration Duration of the scroll animation in ms.
+ * @param {number} x The x-value to scroll to.
+ * @param {number} y The y-value to scroll to.
+ * @param {number} duration Duration of the scroll animation in ms.
* @param {TODO} tolerance TODO
* @returns {Promise} Returns a promise when done
*/
@@ -278,19 +279,19 @@ export class Content extends Ion {
/**
* @private
* Returns the content and scroll elements' dimensions.
- * @returns {Object} dimensions The content and scroll elements' dimensions
- * {Number} dimensions.contentHeight content offsetHeight
- * {Number} dimensions.contentTop content offsetTop
- * {Number} dimensions.contentBottom content offsetTop+offsetHeight
- * {Number} dimensions.contentWidth content offsetWidth
- * {Number} dimensions.contentLeft content offsetLeft
- * {Number} dimensions.contentRight content offsetLeft + offsetWidth
- * {Number} dimensions.scrollHeight scroll scrollHeight
- * {Number} dimensions.scrollTop scroll scrollTop
- * {Number} dimensions.scrollBottom scroll scrollTop + scrollHeight
- * {Number} dimensions.scrollWidth scroll scrollWidth
- * {Number} dimensions.scrollLeft scroll scrollLeft
- * {Number} dimensions.scrollRight scroll scrollLeft + scrollWidth
+ * @returns {object} dimensions The content and scroll elements' dimensions
+ * {number} dimensions.contentHeight content offsetHeight
+ * {number} dimensions.contentTop content offsetTop
+ * {number} dimensions.contentBottom content offsetTop+offsetHeight
+ * {number} dimensions.contentWidth content offsetWidth
+ * {number} dimensions.contentLeft content offsetLeft
+ * {number} dimensions.contentRight content offsetLeft + offsetWidth
+ * {number} dimensions.scrollHeight scroll scrollHeight
+ * {number} dimensions.scrollTop scroll scrollTop
+ * {number} dimensions.scrollBottom scroll scrollTop + scrollHeight
+ * {number} dimensions.scrollWidth scroll scrollWidth
+ * {number} dimensions.scrollLeft scroll scrollLeft
+ * {number} dimensions.scrollRight scroll scrollLeft + scrollWidth
*/
getContentDimensions() {
let _scrollEle = this.scrollElement;
diff --git a/ionic/components/grid/test/alignment/index.ts b/ionic/components/grid/test/alignment/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/grid/test/alignment/index.ts
+++ b/ionic/components/grid/test/alignment/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/grid/test/basic/index.ts b/ionic/components/grid/test/basic/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/grid/test/basic/index.ts
+++ b/ionic/components/grid/test/basic/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/grid/test/full/index.ts b/ionic/components/grid/test/full/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/grid/test/full/index.ts
+++ b/ionic/components/grid/test/full/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/icon/icon.ts b/ionic/components/icon/icon.ts
index 7f821d867d..45b99af1b5 100644
--- a/ionic/components/icon/icon.ts
+++ b/ionic/components/icon/icon.ts
@@ -30,15 +30,7 @@ import {Config} from '../../config/config';
*
* ```
*
- * @property {string} [name] - Use the appropriate icon for the mode.
- * @property {string} [ios] - Explicitly set the icon to use on iOS.
- * @property {string} [md] - Explicitly set the icon to use on Android.
- * @property {boolean} [isActive] - Whether or not the icon has an "active"
- * appearance. On iOS an active icon is filled in or full appearance, and an
- * inactive icon on iOS will use an outlined version of the icon same icon.
- * Material Design icons do not change appearance depending if they're active
- * or not. The `isActive` property is largely used by the tabbar.
- * @demo /docs/v2/demos/icon/
+ * @demo /docs/v2/demos/icon/
* @see {@link /docs/v2/components#icons Icon Component Docs}
*
*/
@@ -85,7 +77,7 @@ export class Icon {
}
/**
- * @private
+ * @input {string} Icon to use. Will load the appropriate icon for each mode
*/
@Input()
get name(): string {
@@ -103,7 +95,7 @@ export class Icon {
}
/**
- * @private
+ * @input {string} Explicitly set the icon to use on iOS
*/
@Input()
get ios(): string {
@@ -116,7 +108,7 @@ export class Icon {
}
/**
- * @private
+ * @input {string} Explicitly set the icon to use on MD
*/
@Input()
get md(): string {
@@ -128,8 +120,9 @@ export class Icon {
this.update();
}
+
/**
- * @private
+ * @input {bool} Whether or not the icon has an "active" appearance. On iOS an active icon is filled in or full appearance, and an inactive icon on iOS will use an outlined version of the icon same icon. Material Design icons do not change appearance depending if they're active or not. The `isActive` property is largely used by the tabbar.
*/
@Input()
get isActive(): boolean {
diff --git a/ionic/components/icon/test/basic/index.ts b/ionic/components/icon/test/basic/index.ts
index 13798b4acc..e390fb7f11 100644
--- a/ionic/components/icon/test/basic/index.ts
+++ b/ionic/components/icon/test/basic/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/input/input.scss b/ionic/components/input/input.scss
index e41563a460..e589b2f17a 100644
--- a/ionic/components/input/input.scss
+++ b/ionic/components/input/input.scss
@@ -5,12 +5,18 @@
ion-input,
ion-textarea {
+ position: relative;
display: block;
flex: 1;
width: 100%;
}
+.item-input ion-input,
+.item-input ion-textarea {
+ position: static;
+}
+
// Textarea Within An Item
// --------------------------------------------------
diff --git a/ionic/components/input/input.ts b/ionic/components/input/input.ts
index e45406d2c6..64d8655495 100644
--- a/ionic/components/input/input.ts
+++ b/ionic/components/input/input.ts
@@ -129,14 +129,14 @@ export class TextInput extends InputBase {
*
* ```
*
- * @demo /docs/v2/demos/textarea/
+ * @demo /docs/v2/demos/textarea/
*/
@Component({
selector: 'ion-textarea',
template:
'' +
' ' +
- '
',
+ '
',
directives: [
NgIf,
NextInput,
diff --git a/ionic/components/input/test/fixed-inline-labels/index.ts b/ionic/components/input/test/fixed-inline-labels/index.ts
index 82ea1a071b..bb337d3a10 100644
--- a/ionic/components/input/test/fixed-inline-labels/index.ts
+++ b/ionic/components/input/test/fixed-inline-labels/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/input/test/floating-labels/index.ts b/ionic/components/input/test/floating-labels/index.ts
index a5b58ac16d..35e138caf5 100644
--- a/ionic/components/input/test/floating-labels/index.ts
+++ b/ionic/components/input/test/floating-labels/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/input/test/form-inputs/index.ts b/ionic/components/input/test/form-inputs/index.ts
index 0a4f0fd1e2..1c48bec6eb 100644
--- a/ionic/components/input/test/form-inputs/index.ts
+++ b/ionic/components/input/test/form-inputs/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
import {FormBuilder, Validators} from 'angular2/common';
diff --git a/ionic/components/input/test/inline-labels/index.ts b/ionic/components/input/test/inline-labels/index.ts
index a9bdbc8a78..7c1848b72b 100644
--- a/ionic/components/input/test/inline-labels/index.ts
+++ b/ionic/components/input/test/inline-labels/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/input/test/input-focus/index.ts b/ionic/components/input/test/input-focus/index.ts
index b8a6ae0b86..f6216ae6b9 100644
--- a/ionic/components/input/test/input-focus/index.ts
+++ b/ionic/components/input/test/input-focus/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/input/test/inset-inputs/index.ts b/ionic/components/input/test/inset-inputs/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/input/test/inset-inputs/index.ts
+++ b/ionic/components/input/test/inset-inputs/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/input/test/placeholder-labels/index.ts b/ionic/components/input/test/placeholder-labels/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/input/test/placeholder-labels/index.ts
+++ b/ionic/components/input/test/placeholder-labels/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/input/test/stacked-labels/index.ts b/ionic/components/input/test/stacked-labels/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/input/test/stacked-labels/index.ts
+++ b/ionic/components/input/test/stacked-labels/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/input/test/text-input.spec.ts b/ionic/components/input/test/text-input.spec.ts
index e8bf672c8b..54418e9014 100644
--- a/ionic/components/input/test/text-input.spec.ts
+++ b/ionic/components/input/test/text-input.spec.ts
@@ -1,4 +1,4 @@
-import {TextInput} from 'ionic/ionic';
+import {TextInput} from '../../../../ionic/ionic';
export function run() {
diff --git a/ionic/components/item/item-sliding-gesture.ts b/ionic/components/item/item-sliding-gesture.ts
index 3f1095e5e1..56b587aa37 100644
--- a/ionic/components/item/item-sliding-gesture.ts
+++ b/ionic/components/item/item-sliding-gesture.ts
@@ -138,7 +138,7 @@ export class ItemSlidingGesture extends DragGesture {
if (this.getOpenAmount(itemContainerEle) < (restingPoint / 2)) {
// If we are going left but too slow, or going right, go back to resting
- if (ev.direction & Hammer.DIRECTION_RIGHT || Math.abs(ev.velocityX) < 0.3) {
+ if (ev.direction & DIRECTION_RIGHT || Math.abs(ev.velocityX) < 0.3) {
restingPoint = 0;
}
}
diff --git a/ionic/components/item/item-sliding.scss b/ionic/components/item/item-sliding.scss
index 11a56bf6a9..db8698663b 100644
--- a/ionic/components/item/item-sliding.scss
+++ b/ionic/components/item/item-sliding.scss
@@ -32,8 +32,20 @@ ion-item-options .button {
height: 100%;
}
-ion-item-sliding.active-slide {
+ion-item-options:not([icon-left]) .button-icon-left {
+ font-size: 14px;
+ .button-inner {
+ flex-direction: column;
+ }
+ ion-icon {
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+ padding-bottom: 0.3em;
+ }
+}
+
+ion-item-sliding.active-slide {
.item,
.item.activated {
diff --git a/ionic/components/item/item.scss b/ionic/components/item/item.scss
index 0ea7f6823e..d75625f8d9 100644
--- a/ionic/components/item/item.scss
+++ b/ionic/components/item/item.scss
@@ -30,6 +30,7 @@
padding: 0;
border: 0;
overflow: hidden;
+ min-height: inherit;
flex: 1;
flex-direction: inherit;
diff --git a/ionic/components/item/test/buttons/index.ts b/ionic/components/item/test/buttons/index.ts
index 2afa53ee3b..1759142cf0 100644
--- a/ionic/components/item/test/buttons/index.ts
+++ b/ionic/components/item/test/buttons/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/item/test/buttons/main.html b/ionic/components/item/test/buttons/main.html
index 4a54f239ea..3d8e56f27b 100644
--- a/ionic/components/item/test/buttons/main.html
+++ b/ionic/components/item/test/buttons/main.html
@@ -88,4 +88,8 @@
View
+
+ ng-for {{i}}
+
+
diff --git a/ionic/components/item/test/dividers/index.ts b/ionic/components/item/test/dividers/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/item/test/dividers/index.ts
+++ b/ionic/components/item/test/dividers/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/item/test/groups/index.ts b/ionic/components/item/test/groups/index.ts
index 806adf048d..40545aad83 100644
--- a/ionic/components/item/test/groups/index.ts
+++ b/ionic/components/item/test/groups/index.ts
@@ -1,4 +1,4 @@
-import {App, Page, NavController, NavParams} from 'ionic/ionic';
+import {App, Page, NavController, NavParams} from '../../../../../ionic/ionic';
@Page({
diff --git a/ionic/components/item/test/images/index.ts b/ionic/components/item/test/images/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/item/test/images/index.ts
+++ b/ionic/components/item/test/images/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/item/test/media/index.ts b/ionic/components/item/test/media/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/item/test/media/index.ts
+++ b/ionic/components/item/test/media/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/item/test/sliding/index.ts b/ionic/components/item/test/sliding/index.ts
index 6b8723c9b7..196760ef88 100644
--- a/ionic/components/item/test/sliding/index.ts
+++ b/ionic/components/item/test/sliding/index.ts
@@ -1,4 +1,4 @@
-import {App, Page, IonicApp, Alert, NavController} from 'ionic/ionic';
+import {App, Page, IonicApp, Alert, NavController} from '../../../../../ionic/ionic';
@Page({
diff --git a/ionic/components/item/test/sliding/main.html b/ionic/components/item/test/sliding/main.html
index 9240f6b270..d98eb5b2ad 100644
--- a/ionic/components/item/test/sliding/main.html
+++ b/ionic/components/item/test/sliding/main.html
@@ -31,7 +31,9 @@
Archive
-
+
+
+
@@ -53,8 +55,10 @@
One Line w/ Icon, div only text
-
- Archive
+
+
+ Archive
+
@@ -66,7 +70,16 @@
One Line w/ Avatar, div only text
- Archive
+
+ More
+
+
+ Archive
+
+
+ Delete
+
+
@@ -104,4 +117,4 @@
img {
height: 100px;
}
-
+
\ No newline at end of file
diff --git a/ionic/components/item/test/text/index.ts b/ionic/components/item/test/text/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/item/test/text/index.ts
+++ b/ionic/components/item/test/text/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/label/test/basic/index.ts b/ionic/components/label/test/basic/index.ts
deleted file mode 100644
index ac2d757460..0000000000
--- a/ionic/components/label/test/basic/index.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import {App} from 'ionic/ionic';
-
-
-@App({
- templateUrl: 'main.html'
-})
-class E2EApp {
- constructor() {
- }
-}
diff --git a/ionic/components/label/test/basic/main.html b/ionic/components/label/test/basic/main.html
deleted file mode 100644
index b57fb20282..0000000000
--- a/ionic/components/label/test/basic/main.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
- Icons
-
-
-
-
-
- Username
-
-
-
-
diff --git a/ionic/components/list/list.ts b/ionic/components/list/list.ts
index 1c8390c59b..84bf9aee6b 100644
--- a/ionic/components/list/list.ts
+++ b/ionic/components/list/list.ts
@@ -113,7 +113,7 @@ export class List extends Ion {
* }
* }
* ```
- * @param {Boolean} shouldEnable whether the item-sliding should be enabled or not
+ * @param {boolean} shouldEnable whether the item-sliding should be enabled or not
*/
enableSlidingItems(shouldEnable: boolean) {
if (this._enableSliding !== shouldEnable) {
diff --git a/ionic/components/list/test/headers/index.ts b/ionic/components/list/test/headers/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/list/test/headers/index.ts
+++ b/ionic/components/list/test/headers/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/list/test/infinite/index.ts b/ionic/components/list/test/infinite/index.ts
index 9164945f91..bbfbeb77cf 100644
--- a/ionic/components/list/test/infinite/index.ts
+++ b/ionic/components/list/test/infinite/index.ts
@@ -1,42 +1,9 @@
-import {ProtoViewRef, ViewContainerRef} from 'angular2/core'
-import {Directive, Host, forwardRef} from 'angular2/core';
-
-import {App, List} from 'ionic/ionic';
-
+import {App} from '../../../../../ionic/ionic';
@App({
- templateUrl: 'main.html',
- directives: [forwardRef(() => ItemCellTemplate)]
+ templateUrl: 'main.html'
})
class E2EApp {
- constructor() {
-
- this.items = []
- for(let i = 0; i < 1000; i++) {
- this.items.push({
- title: 'Item ' + i
- })
- }
- }
-}
-
-
-/*
- 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[cell]'
-})
-export class ItemCellTemplate {
- constructor(@Host() list: List, viewContainer: ViewContainerRef, protoViewRef: ProtoViewRef) {
- console.log('Item cell template', list, viewContainer, protoViewRef);
-
- this.protoViewRef = protoViewRef;
- this.viewContainer = viewContainer;
-
- list.setItemTemplate(this);
- }
+ // TODO
}
diff --git a/ionic/components/list/test/infinite/main.html b/ionic/components/list/test/infinite/main.html
index d6f233e191..0b680180a1 100644
--- a/ionic/components/list/test/infinite/main.html
+++ b/ionic/components/list/test/infinite/main.html
@@ -1,10 +1,7 @@
-
+Infinite List
-
-
- {{item.title}}
-
-
-
+
+
+TODO
diff --git a/ionic/components/list/test/inset/index.ts b/ionic/components/list/test/inset/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/list/test/inset/index.ts
+++ b/ionic/components/list/test/inset/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/list/test/no-lines/index.ts b/ionic/components/list/test/no-lines/index.ts
index 43aed36502..6a30176f2a 100644
--- a/ionic/components/list/test/no-lines/index.ts
+++ b/ionic/components/list/test/no-lines/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/list/test/repeat-headers/index.ts b/ionic/components/list/test/repeat-headers/index.ts
index 0aea852e02..55b159d8ab 100644
--- a/ionic/components/list/test/repeat-headers/index.ts
+++ b/ionic/components/list/test/repeat-headers/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/list/test/sticky/index.ts b/ionic/components/list/test/sticky/index.ts
index 0fe2844026..e753b62ae5 100644
--- a/ionic/components/list/test/sticky/index.ts
+++ b/ionic/components/list/test/sticky/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/menu/menu-controller.ts b/ionic/components/menu/menu-controller.ts
index 0172fc71fb..1c1fd69ac3 100644
--- a/ionic/components/menu/menu-controller.ts
+++ b/ionic/components/menu/menu-controller.ts
@@ -120,7 +120,25 @@ import {MenuType} from './menu-types';
* but this can be overriden using the `type` property:
*
* ```html
- *
+ * ...
+ * ```
+ *
+ *
+ * ### Persistent Menus
+ *
+ * By default, menus, and specifically their menu toggle buttons in the navbar,
+ * only show on the root page within its `NavController`. For example, on Page 1
+ * the menu toggle will show in the navbar. However, when navigating to Page 2,
+ * because it is not the root Page for that `NavController`, the menu toggle
+ * will not show in the navbar.
+ *
+ * Not showing the menu toggle button in the navbar is commonly seen within
+ * native apps after navigating past the root Page. However, it is still possible
+ * to always show the menu toggle button in the navbar by setting
+ * `persistent="true"` on the `ion-menu` component.
+ *
+ * ```html
+ * ...
* ```
*
* @demo /docs/v2/demos/menu/
@@ -137,36 +155,54 @@ export class MenuController {
* Progamatically open the Menu.
* @return {Promise} returns a promise when the menu is fully opened
*/
- open(menuId?: string) {
+ open(menuId?: string): Promise {
let menu = this.get(menuId);
if (menu) {
return menu.open();
}
+
+ return Promise.resolve(false);
}
/**
- * Progamatically close the Menu.
+ * Progamatically close the Menu. If no `menuId` is given as the first
+ * argument then it'll close any menu which is open. If a `menuId`
+ * is given then it'll close that exact menu.
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {Promise} returns a promise when the menu is fully closed
*/
- close(menuId?: string) {
- let menu = this.get(menuId);
+ close(menuId?: string): Promise {
+ let menu: Menu;
+
+ if (menuId) {
+ // find the menu by its id
+ menu = this.get(menuId);
+
+ } else {
+ // find the menu that is open
+ menu = this._menus.find(m => m.isOpen);
+ }
+
if (menu) {
+ // close the menu
return menu.close();
}
+
+ return Promise.resolve(false);
}
/**
- * Toggle the menu. If it's closed, it will open, and if opened, it will
- * close.
+ * Toggle the menu. If it's closed, it will open, and if opened, it
+ * will close.
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {Promise} returns a promise when the menu has been toggled
*/
- toggle(menuId?: string) {
+ toggle(menuId?: string): Promise {
let menu = this.get(menuId);
if (menu) {
return menu.toggle();
}
+ return Promise.resolve(false);
}
/**
@@ -176,7 +212,7 @@ export class MenuController {
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {Menu} Returns the instance of the menu, which is useful for chaining.
*/
- enable(shouldEnable: boolean, menuId?: string) {
+ enable(shouldEnable: boolean, menuId?: string): Menu {
let menu = this.get(menuId);
if (menu) {
return menu.enable(shouldEnable);
@@ -189,7 +225,7 @@ export class MenuController {
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {Menu} Returns the instance of the menu, which is useful for chaining.
*/
- swipeEnable(shouldEnable: boolean, menuId?: string) {
+ swipeEnable(shouldEnable: boolean, menuId?: string): Menu {
let menu = this.get(menuId);
if (menu) {
return menu.swipeEnable(shouldEnable);
@@ -197,7 +233,26 @@ export class MenuController {
}
/**
- * Used to get a menu instance.
+ * @return {boolean} Returns true if the menu is currently open, otherwise false.
+ */
+ isOpen(menuId?: string): boolean {
+ let menu = this.get(menuId);
+ return menu && menu.isOpen || false;
+ }
+
+ /**
+ * @return {boolean} Returns true if the menu is currently enabled, otherwise false.
+ */
+ isEnabled(menuId?: string): boolean {
+ let menu = this.get(menuId);
+ return menu && menu.enabled || false;
+ }
+
+ /**
+ * Used to get a menu instance. If a `menuId` is not provided then it'll return
+ * the first menu found. If a `menuId` is provided, then it'll first try to find
+ * the menu using the menu's `id` attribute. If a menu is not found using the `id`
+ * attribute, then it'll try to find the menu by its `side` name.
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {Menu} Returns the instance of the menu if found, otherwise `null`.
*/
@@ -216,6 +271,14 @@ export class MenuController {
return (this._menus.length ? this._menus[0] : null);
}
+
+ /**
+ * @return {Array} Returns an array of all menu instances.
+ */
+ getMenus(): Array {
+ return this._menus;
+ }
+
/**
* @private
*/
diff --git a/ionic/components/menu/menu-gestures.ts b/ionic/components/menu/menu-gestures.ts
index 6746d082a0..8aed15eafe 100644
--- a/ionic/components/menu/menu-gestures.ts
+++ b/ionic/components/menu/menu-gestures.ts
@@ -1,6 +1,6 @@
import {Menu} from './menu';
import {SlideEdgeGesture} from '../../gestures/slide-edge-gesture';
-
+import {SlideData} from '../../gestures/slide-gesture';
import {assign} from '../../util/util';
@@ -17,15 +17,13 @@ export class MenuContentGesture extends SlideEdgeGesture {
threshold: 0,
maxEdgeStart: menu.maxEdgeStart || 75
}, options));
-
- this.listen();
}
- canStart(ev) {
+ canStart(ev: any) {
let menu = this.menu;
- if (!menu.isEnabled || !menu.isSwipeEnabled) {
- console.debug('menu can not start, isEnabled:', menu.isEnabled, 'isSwipeEnabled:', menu.isSwipeEnabled, 'side:', menu.side);
+ if (!menu.enabled || !menu.swipeEnabled) {
+ console.debug('menu can not start, isEnabled:', menu.enabled, 'isSwipeEnabled:', menu.swipeEnabled, 'side:', menu.side);
return false;
}
@@ -70,20 +68,20 @@ export class MenuContentGesture extends SlideEdgeGesture {
}
// Set CSS, then wait one frame for it to apply before sliding starts
- onSlideBeforeStart(slide, ev) {
+ onSlideBeforeStart(slide: SlideData, ev: any) {
console.debug('menu gesture, onSlideBeforeStart', this.menu.side);
- this.menu.setProgressStart();
+ this.menu.swipeStart();
}
- onSlide(slide, ev) {
+ onSlide(slide: SlideData, ev: any) {
let z = (this.menu.side === 'right' ? slide.min : slide.max);
let stepValue = (slide.distance / z);
console.debug('menu gesture, onSlide', this.menu.side, 'distance', slide.distance, 'min', slide.min, 'max', slide.max, 'z', z, 'stepValue', stepValue);
- this.menu.setProgessStep(stepValue);
+ this.menu.swipeProgress(stepValue);
}
- onSlideEnd(slide, ev) {
+ onSlideEnd(slide: SlideData, ev: any) {
let z = (this.menu.side === 'right' ? slide.min : slide.max);
let shouldComplete = (Math.abs(ev.velocityX) > 0.2) ||
@@ -93,10 +91,10 @@ export class MenuContentGesture extends SlideEdgeGesture {
console.debug('menu gesture, onSlide', this.menu.side, 'distance', slide.distance, 'delta', slide.delta, 'velocityX', ev.velocityX, 'min', slide.min, 'max', slide.max, 'shouldComplete', shouldComplete, 'currentStepValue', currentStepValue);
- this.menu.setProgressEnd(shouldComplete, currentStepValue);
+ this.menu.swipeEnd(shouldComplete, currentStepValue);
}
- getElementStartPos(slide, ev) {
+ getElementStartPos(slide: SlideData, ev: any) {
if (this.menu.side === 'right') {
// right menu
return this.menu.isOpen ? slide.min : slide.max;
diff --git a/ionic/components/menu/menu-toggle.ts b/ionic/components/menu/menu-toggle.ts
index 05180d52b4..6826f0d9b6 100644
--- a/ionic/components/menu/menu-toggle.ts
+++ b/ionic/components/menu/menu-toggle.ts
@@ -68,7 +68,17 @@ export class MenuToggle {
*/
get isHidden() {
if (this._inNavbar && this._viewCtrl) {
- return !this._viewCtrl.isRoot();
+ if (this._viewCtrl.isRoot()) {
+ // this is the root view, so it should always show
+ return false;
+ }
+
+ let menu = this._menu.get(this.menuToggle);
+ if (menu) {
+ // this is not the root view, so see if this menu
+ // is configured to still be enabled if it's not the root view
+ return !menu.persistent;
+ }
}
return false;
}
diff --git a/ionic/components/menu/menu.ts b/ionic/components/menu/menu.ts
index 11c9f749de..87104a2cf3 100644
--- a/ionic/components/menu/menu.ts
+++ b/ionic/components/menu/menu.ts
@@ -5,10 +5,9 @@ import {Config} from '../../config/config';
import {Platform} from '../../platform/platform';
import {Keyboard} from '../../util/keyboard';
import {MenuContentGesture, MenuTargetGesture} from './menu-gestures';
-import {Gesture} from '../../gestures/gesture';
import {MenuController} from './menu-controller';
import {MenuType} from './menu-types';
-import {isFalseProperty} from '../../util/util';
+import {isTrueProperty} from '../../util/util';
/**
@@ -17,38 +16,30 @@ import {isFalseProperty} from '../../util/util';
@Component({
selector: 'ion-menu',
host: {
- 'role': 'navigation',
- '[attr.side]': 'side',
- '[attr.type]': 'type',
- '[attr.swipeEnabled]': 'swipeEnabled'
+ 'role': 'navigation'
},
- template: '
',
+ template:
+ ' ' +
+ '
',
directives: [forwardRef(() => MenuBackdrop)]
})
export class Menu extends Ion {
private _preventTime: number = 0;
private _cntEle: HTMLElement;
- private _cntGesture: Gesture;
- private _menuGesture: Gesture;
+ private _cntGesture: MenuTargetGesture;
+ private _menuGesture: MenuContentGesture;
private _type: MenuType;
private _resizeUnreg: Function;
-
+ private _isEnabled: boolean = true;
+ private _isSwipeEnabled: boolean = true;
+ private _isPers: boolean = false;
+ private _init: boolean = false;
/**
* @private
*/
isOpen: boolean = false;
- /**
- * @private
- */
- isEnabled: boolean = true;
-
- /**
- * @private
- */
- isSwipeEnabled: boolean = true;
-
/**
* @private
*/
@@ -59,7 +50,6 @@ export class Menu extends Ion {
*/
onContentClick: EventListener;
-
/**
* @private
*/
@@ -83,17 +73,50 @@ export class Menu extends Ion {
/**
* @private
*/
- @Input() swipeEnabled: any;
+ @Input()
+ get enabled(): boolean {
+ return this._isEnabled;
+ }
+
+ set enabled(val: boolean) {
+ this._isEnabled = isTrueProperty(val);
+ this._setListeners();
+ }
/**
* @private
*/
- @Input() maxEdgeStart;
+ @Input()
+ get swipeEnabled(): boolean {
+ return this._isSwipeEnabled;
+ }
+
+ set swipeEnabled(val: boolean) {
+ this._isSwipeEnabled = isTrueProperty(val);
+ this._setListeners();
+ }
/**
* @private
*/
- @Output() opening: EventEmitter = new EventEmitter();
+ @Input()
+ get persistent(): boolean {
+ return this._isPers;
+ }
+
+ set persistent(val: boolean) {
+ this._isPers = isTrueProperty(val);
+ }
+
+ /**
+ * @private
+ */
+ @Input() maxEdgeStart: number;
+
+ /**
+ * @private
+ */
+ @Output() opening: EventEmitter = new EventEmitter();
constructor(
private _menuCtrl: MenuController,
@@ -112,6 +135,8 @@ export class Menu extends Ion {
*/
ngOnInit() {
let self = this;
+ self._init = true;
+
let content = self.content;
self._cntEle = (content instanceof Node) ? content : content && content.getNativeElement && content.getNativeElement();
@@ -132,23 +157,29 @@ export class Menu extends Ion {
}
self._renderer.setElementAttribute(self._elementRef.nativeElement, 'type', self.type);
- // add the gesture listeners
- self._zone.runOutsideAngular(function() {
- self._cntGesture = new MenuContentGesture(self, self.getContentElement());
- self._menuGesture = new MenuTargetGesture(self, self.getNativeElement());
+ // add the gestures
+ self._cntGesture = new MenuContentGesture(self, self.getContentElement());
+ self._menuGesture = new MenuTargetGesture(self, self.getNativeElement());
- self.onContentClick = function(ev: UIEvent) {
- if (self.isEnabled) {
- ev.preventDefault();
- ev.stopPropagation();
- self.close();
- }
- };
+ // register listeners if this menu is enabled
+ // check if more than one menu is on the same side
+ let hasEnabledSameSideMenu = self._menuCtrl.getMenus().some(m => {
+ return m.side === self.side && m.enabled;
});
-
- if (isFalseProperty(self.swipeEnabled)) {
- self.isSwipeEnabled = false;
+ if (hasEnabledSameSideMenu) {
+ // auto-disable if another menu on the same side is already enabled
+ self._isEnabled = false;
}
+ self._setListeners();
+
+ // create a reusable click handler on this instance, but don't assign yet
+ self.onContentClick = function(ev: UIEvent) {
+ if (self._isEnabled) {
+ ev.preventDefault();
+ ev.stopPropagation();
+ self.close();
+ }
+ };
self._cntEle.classList.add('menu-content');
self._cntEle.classList.add('menu-content-' + self.type);
@@ -157,6 +188,32 @@ export class Menu extends Ion {
self._menuCtrl.register(self);
}
+ /**
+ * @private
+ */
+ private _setListeners() {
+ let self = this;
+
+ if (self._init) {
+ // only listen/unlisten if the menu has initialized
+
+ if (self._isEnabled && self._isSwipeEnabled && !self._cntGesture.isListening) {
+ // should listen, but is not currently listening
+ console.debug('menu, gesture listen', self.side);
+ self._zone.runOutsideAngular(function() {
+ self._cntGesture.listen();
+ self._menuGesture.listen();
+ });
+
+ } else if (self._cntGesture.isListening && (!self._isEnabled || !self._isSwipeEnabled)) {
+ // should not listen, but is currently listening
+ console.debug('menu, gesture unlisten', self.side);
+ self._cntGesture.unlisten();
+ self._menuGesture.unlisten();
+ }
+ }
+ }
+
/**
* @private
*/
@@ -176,7 +233,7 @@ export class Menu extends Ion {
* @param {boolean} shouldOpen If the Menu is open or not.
* @return {Promise} returns a promise once set
*/
- setOpen(shouldOpen): Promise {
+ setOpen(shouldOpen: boolean): Promise {
// _isPrevented is used to prevent unwanted opening/closing after swiping open/close
// or swiping open the menu while pressing down on the menuToggle button
if ((shouldOpen && this.isOpen) || this._isPrevented()) {
@@ -196,9 +253,9 @@ export class Menu extends Ion {
/**
* @private
*/
- setProgressStart() {
+ swipeStart() {
// user started swiping the menu open/close
- if (this._isPrevented() || !this.isEnabled || !this.isSwipeEnabled) return;
+ if (this._isPrevented() || !this._isEnabled || !this._isSwipeEnabled) return;
this._before();
this._getType().setProgressStart(this.isOpen);
@@ -207,9 +264,9 @@ export class Menu extends Ion {
/**
* @private
*/
- setProgessStep(stepValue: number) {
+ swipeProgress(stepValue: number) {
// user actively dragging the menu
- if (this.isEnabled && this.isSwipeEnabled) {
+ if (this._isEnabled && this._isSwipeEnabled) {
this._prevent();
this._getType().setProgessStep(stepValue);
this.opening.next(stepValue);
@@ -219,12 +276,12 @@ export class Menu extends Ion {
/**
* @private
*/
- setProgressEnd(shouldComplete: boolean, currentStepValue: number) {
+ swipeEnd(shouldComplete: boolean, currentStepValue: number) {
// user has finished dragging the menu
- if (this.isEnabled && this.isSwipeEnabled) {
+ if (this._isEnabled && this._isSwipeEnabled) {
this._prevent();
this._getType().setProgressEnd(shouldComplete, currentStepValue, (isOpen) => {
- console.debug('menu, progress end', this.side);
+ console.debug('menu, swipeEnd', this.side);
this._after(isOpen);
});
}
@@ -236,7 +293,7 @@ export class Menu extends Ion {
private _before() {
// this places the menu into the correct location before it animates in
// this css class doesn't actually kick off any animations
- if (this.isEnabled) {
+ if (this._isEnabled) {
this.getNativeElement().classList.add('show-menu');
this.getBackdropElement().classList.add('show-backdrop');
@@ -252,7 +309,7 @@ export class Menu extends Ion {
// keep opening/closing the menu disabled for a touch more yet
// only add listeners/css if it's enabled and isOpen
// and only remove listeners/css if it's not open
- if ((this.isEnabled && isOpen) || !isOpen) {
+ if ((this._isEnabled && isOpen) || !isOpen) {
this._prevent();
this.isOpen = isOpen;
@@ -318,7 +375,7 @@ export class Menu extends Ion {
* @return {Menu} Returns the instance of the menu, which is useful for chaining.
*/
enable(shouldEnable: boolean): Menu {
- this.isEnabled = shouldEnable;
+ this.enabled = shouldEnable;
if (!shouldEnable && this.isOpen) {
this.close();
}
@@ -331,7 +388,7 @@ export class Menu extends Ion {
* @return {Menu} Returns the instance of the menu, which is useful for chaining.
*/
swipeEnable(shouldEnable: boolean): Menu {
- this.isSwipeEnabled = shouldEnable;
+ this.swipeEnabled = shouldEnable;
return this;
}
diff --git a/ionic/components/menu/test/basic/e2e.ts b/ionic/components/menu/test/basic/e2e.ts
index f9f2e51243..ee5aa0f45e 100644
--- a/ionic/components/menu/test/basic/e2e.ts
+++ b/ionic/components/menu/test/basic/e2e.ts
@@ -5,5 +5,5 @@ it('should toggle open menu', function() {
it('should close menu', function() {
- element(by.css('[menuClose=left]')).click();
+ element(by.css('.e2eCloseLeftMenu')).click();
});
diff --git a/ionic/components/menu/test/basic/index.ts b/ionic/components/menu/test/basic/index.ts
index fa8d5e3f4a..3cc926fbba 100644
--- a/ionic/components/menu/test/basic/index.ts
+++ b/ionic/components/menu/test/basic/index.ts
@@ -1,4 +1,4 @@
-import {App, IonicApp, MenuController, Page, NavController, Alert} from 'ionic/ionic';
+import {App, IonicApp, MenuController, Page, NavController, Alert} from '../../../../../ionic/ionic';
@Page({
@@ -37,10 +37,12 @@ class Page2 {
templateUrl: 'main.html'
})
class E2EApp {
+ rootPage;
+ changeDetectionCount: number = 0;
+ pages: Array<{title: string, component: any}>;
constructor(private app: IonicApp, private menu: MenuController) {
- this.rootView = Page1;
- this.changeDetectionCount = 0;
+ this.rootPage = Page1;
this.pages = [
{ title: 'Page 1', component: Page1 },
@@ -56,7 +58,7 @@ class E2EApp {
nav.setRoot(page.component).then(() => {
// wait for the root page to be completely loaded
// then close the menu
- this.menu.close('left');
+ this.menu.close();
});
}
diff --git a/ionic/components/menu/test/basic/main.html b/ionic/components/menu/test/basic/main.html
index 8ca9375f0a..9c1a9f1ca3 100644
--- a/ionic/components/menu/test/basic/main.html
+++ b/ionic/components/menu/test/basic/main.html
@@ -1,4 +1,4 @@
-
+
Left Menu
@@ -12,7 +12,7 @@
{{p.title}}
-
+
@@ -138,6 +138,6 @@
-
+
\ No newline at end of file
diff --git a/ionic/components/menu/test/basic/page3.html b/ionic/components/menu/test/basic/page3.html
index 1b631ce4a1..e05fc4807b 100644
--- a/ionic/components/menu/test/basic/page3.html
+++ b/ionic/components/menu/test/basic/page3.html
@@ -1,6 +1,10 @@
+
+
+
+
Menu
diff --git a/ionic/components/menu/test/disable-swipe/index.ts b/ionic/components/menu/test/disable-swipe/index.ts
index c255978493..f082752d49 100644
--- a/ionic/components/menu/test/disable-swipe/index.ts
+++ b/ionic/components/menu/test/disable-swipe/index.ts
@@ -1,4 +1,4 @@
-import {App, Page, NavController, MenuController} from 'ionic/ionic';
+import {App, Page, NavController, MenuController} from '../../../../../ionic/ionic';
@Page({
templateUrl: 'page1.html'
@@ -14,13 +14,13 @@ class Page1 {
toggleLeftMenuSwipeable() {
this.leftMenuSwipeEnabled = !this.leftMenuSwipeEnabled;
- this.menu.swipeEnable(this.leftMenuSwipeEnabled, 'leftMenu');
+ this.menu.swipeEnable(this.leftMenuSwipeEnabled, 'left');
}
toggleRightMenuSwipeable() {
this.rightMenuSwipeEnabled = !this.rightMenuSwipeEnabled;
- this.menu.swipeEnable(this.leftMenuSwipeEnabled, 'rightMenu');
+ this.menu.swipeEnable(this.rightMenuSwipeEnabled, 'right');
}
}
diff --git a/ionic/components/menu/test/disable-swipe/main.html b/ionic/components/menu/test/disable-swipe/main.html
index b687ca825e..71b314b01c 100644
--- a/ionic/components/menu/test/disable-swipe/main.html
+++ b/ionic/components/menu/test/disable-swipe/main.html
@@ -7,11 +7,9 @@
-
Left Item 1
-
@@ -27,11 +25,9 @@
-
Right Item 1
-
diff --git a/ionic/components/menu/test/multiple/index.ts b/ionic/components/menu/test/multiple/index.ts
index 46e9d35e60..eaab81dc85 100644
--- a/ionic/components/menu/test/multiple/index.ts
+++ b/ionic/components/menu/test/multiple/index.ts
@@ -1,12 +1,13 @@
-import {App, Page, MenuController} from 'ionic/ionic';
+import {App, Page, MenuController} from '../../../../../ionic/ionic';
@Page({
templateUrl: 'page1.html'
})
class Page1 {
- constructor(menu: MenuController) {
- this.menu = menu;
+ activeMenu: string;
+
+ constructor(private menu: MenuController) {
this.menu1Active();
}
menu1Active() {
@@ -26,6 +27,8 @@ class Page1 {
templateUrl: 'main.html'
})
class E2EApp {
+ rootPage;
+
constructor() {
this.rootPage = Page1;
}
diff --git a/ionic/components/menu/test/overlay/index.ts b/ionic/components/menu/test/overlay/index.ts
index 849c7cbed5..02f1dee577 100644
--- a/ionic/components/menu/test/overlay/index.ts
+++ b/ionic/components/menu/test/overlay/index.ts
@@ -1,4 +1,4 @@
-import {App, IonicApp, Page} from 'ionic/ionic';
+import {App, IonicApp, Page} from '../../../../../ionic/ionic';
@Page({templateUrl: 'page1.html'})
diff --git a/ionic/components/menu/test/push/index.ts b/ionic/components/menu/test/push/index.ts
index 849c7cbed5..02f1dee577 100644
--- a/ionic/components/menu/test/push/index.ts
+++ b/ionic/components/menu/test/push/index.ts
@@ -1,4 +1,4 @@
-import {App, IonicApp, Page} from 'ionic/ionic';
+import {App, IonicApp, Page} from '../../../../../ionic/ionic';
@Page({templateUrl: 'page1.html'})
diff --git a/ionic/components/menu/test/reveal/index.ts b/ionic/components/menu/test/reveal/index.ts
index 849c7cbed5..02f1dee577 100644
--- a/ionic/components/menu/test/reveal/index.ts
+++ b/ionic/components/menu/test/reveal/index.ts
@@ -1,4 +1,4 @@
-import {App, IonicApp, Page} from 'ionic/ionic';
+import {App, IonicApp, Page} from '../../../../../ionic/ionic';
@Page({templateUrl: 'page1.html'})
diff --git a/ionic/components/modal/modal.ts b/ionic/components/modal/modal.ts
index 623540823f..2ed614c42f 100644
--- a/ionic/components/modal/modal.ts
+++ b/ionic/components/modal/modal.ts
@@ -1,5 +1,6 @@
import {ViewController} from '../nav/view-controller';
import {Animation} from '../../animations/animation';
+import {Transition, TransitionOptions} from '../../transitions/transition';
/**
* @name Modal
@@ -116,8 +117,8 @@ export class Modal extends ViewController {
}
/**
- * @param {Any} componentType Modal
- * @param {Object} data Modal options
+ * @param {any} componentType Modal
+ * @param {object} data Modal options
*/
static create(componentType, data={}) {
return new Modal(componentType, data);
@@ -129,10 +130,11 @@ export class Modal extends ViewController {
/**
* Animations for modals
*/
-class ModalSlideIn extends Animation {
- constructor(enteringView, leavingView, opts) {
- super(enteringView.pageRef(), opts);
+class ModalSlideIn extends Transition {
+ constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
+ super(opts);
this
+ .element(enteringView.pageRef())
.easing('cubic-bezier(0.36,0.66,0.04,1)')
.duration(400)
.fromTo('translateY', '100%', '0%')
@@ -146,25 +148,27 @@ class ModalSlideIn extends Animation {
}
}
}
-Animation.register('modal-slide-in', ModalSlideIn);
+Transition.register('modal-slide-in', ModalSlideIn);
-class ModalSlideOut extends Animation {
- constructor(enteringView, leavingView, opts) {
- super(leavingView.pageRef(), opts);
+class ModalSlideOut extends Transition {
+ constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
+ super(opts);
this
+ .element(leavingView.pageRef())
.easing('ease-out')
.duration(250)
.fromTo('translateY', '0%', '100%');
}
}
-Animation.register('modal-slide-out', ModalSlideOut);
+Transition.register('modal-slide-out', ModalSlideOut);
-class ModalMDSlideIn extends Animation {
- constructor(enteringView, leavingView, opts) {
- super(enteringView.pageRef(), opts);
+class ModalMDSlideIn extends Transition {
+ constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
+ super(opts);
this
+ .element(enteringView.pageRef())
.easing('cubic-bezier(0.36,0.66,0.04,1)')
.duration(280)
.fromTo('translateY', '40px', '0px')
@@ -179,17 +183,18 @@ class ModalMDSlideIn extends Animation {
}
}
}
-Animation.register('modal-md-slide-in', ModalMDSlideIn);
+Transition.register('modal-md-slide-in', ModalMDSlideIn);
-class ModalMDSlideOut extends Animation {
- constructor(enteringView, leavingView, opts) {
- super(leavingView.pageRef(), opts);
+class ModalMDSlideOut extends Transition {
+ constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
+ super(opts);
this
+ .element(leavingView.pageRef())
.duration(200)
.easing('cubic-bezier(0.47,0,0.745,0.715)')
.fromTo('translateY', '0px', '40px')
.fadeOut();
}
}
-Animation.register('modal-md-slide-out', ModalMDSlideOut);
+Transition.register('modal-md-slide-out', ModalMDSlideOut);
diff --git a/ionic/components/modal/test/basic/index.ts b/ionic/components/modal/test/basic/index.ts
index c4144aa706..713e88f314 100644
--- a/ionic/components/modal/test/basic/index.ts
+++ b/ionic/components/modal/test/basic/index.ts
@@ -1,5 +1,5 @@
-import {App, Page, Config, Platform} from 'ionic/ionic';
-import {Modal, ActionSheet, NavController, NavParams, Animation, ViewController} from 'ionic/ionic';
+import {App, Page, Config, Platform} from '../../../../../ionic/ionic';
+import {Modal, ActionSheet, NavController, NavParams, Transition, TransitionOptions, ViewController} from '../../../../../ionic/ionic';;
@Page({
@@ -284,10 +284,11 @@ class E2EApp {
}
-class FadeIn extends Animation {
- constructor(enteringView, leavingView) {
- super(enteringView.pageRef());
+class FadeIn extends Transition {
+ constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
+ super(opts);
this
+ .element(enteringView.pageRef())
.easing('ease')
.duration(1000)
.fromTo('translateY', '0%', '0%')
@@ -295,16 +296,17 @@ class FadeIn extends Animation {
.before.addClass('show-page');
}
}
-Animation.register('my-fade-in', FadeIn);
+Transition.register('my-fade-in', FadeIn);
-class FadeOut extends Animation {
- constructor(enteringView, leavingView) {
- super(leavingView.pageRef());
+class FadeOut extends Transition {
+ constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
+ super(opts);
this
+ .element(leavingView.pageRef())
.easing('ease')
.duration(500)
.fadeOut()
.before.addClass('show-page');
}
}
-Animation.register('my-fade-out', FadeOut);
+Transition.register('my-fade-out', FadeOut);
diff --git a/ionic/components/nav/nav-controller.ts b/ionic/components/nav/nav-controller.ts
index 5ca801f04f..65a7f818bf 100644
--- a/ionic/components/nav/nav-controller.ts
+++ b/ionic/components/nav/nav-controller.ts
@@ -1,16 +1,16 @@
-import {Compiler, ElementRef, Injector, provide, NgZone, AppViewManager, Renderer, ResolvedProvider, Type} from 'angular2/core';
+import {Compiler, ElementRef, Injector, provide, NgZone, AppViewManager, Renderer, ResolvedProvider, Type, Input} from 'angular2/core';
import {wtfLeave, wtfCreateScope, WtfScopeFn, wtfStartTimeRange, wtfEndTimeRange} from 'angular2/instrumentation';
-import {Animation} from '../../animations/animation';
import {Config} from '../../config/config';
import {Ion} from '../ion';
import {IonicApp} from '../app/app';
-import {isBoolean, array, pascalCaseToDashCase} from '../../util/util';
import {Keyboard} from '../../util/keyboard';
import {NavParams} from './nav-params';
import {NavRouter} from './nav-router';
-import {raf, rafFrames} from '../../util/dom';
+import {pascalCaseToDashCase, isTrueProperty} from '../../util/util';
+import {raf} from '../../util/dom';
import {SwipeBackGesture} from './swipe-back';
+import {Transition} from '../../transitions/transition';
import {ViewController} from './view-controller';
/**
@@ -106,11 +106,12 @@ import {ViewController} from './view-controller';
export class NavController extends Ion {
private _transIds = 0;
private _init = false;
- private _lastTrans;
+ private _trans: Transition;
+ private _sbGesture: SwipeBackGesture;
+ private _sbEnabled: boolean;
+ private _sbThreshold: number;
+
protected _ids: number = -1;
- protected _sbEnabled: any;
- protected _sbThreshold: any;
- protected _sbTrans: any = null;
protected _trnsDelay: any;
protected _trnsTime: number = 0;
protected _views: Array = [];
@@ -133,12 +134,7 @@ export class NavController extends Ion {
/**
* @private
*/
- sbGesture: any;
-
- /**
- * @private
- */
- parent;
+ parent: any;
/**
* @private
@@ -164,7 +160,7 @@ export class NavController extends Ion {
this._trnsDelay = config.get('pageTransitionDelay');
- this._sbEnabled = config.get('swipeBackEnabled') || false;
+ this._sbEnabled = config.getBoolean('swipeBackEnabled') || false;
this._sbThreshold = config.get('swipeBackThreshold') || 40;
this.id = ++ctrlIds;
@@ -182,7 +178,7 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass to transtion
* @returns {Promise} Returns a promise when done
*/
- setRoot(page: Type, params: any = {}, opts: any = {}): Promise {
+ setRoot(page: Type, params: any = {}, opts: NavOptions = {}): Promise {
return this.setPages([{page, params}], opts);
}
@@ -255,13 +251,13 @@ export class NavController extends Ion {
* }
*```
*
- * @param {Array} pages An arry of page components and their params to load in the stack
+ * @param {array} pages An arry of page components and their params to load in the stack
* @param {object} [opts={}] Any options you want to use pass
* @returns {Promise} Returns a promise when the pages are set
*/
- setPages(pages: Array<{page: Type, params?: any}>, opts: any = {}): Promise {
+ setPages(pages: Array<{page: Type, params?: any}>, opts: NavOptions = {}): Promise {
if (!pages || !pages.length) {
- return Promise.resolve();
+ return Promise.resolve(false);
}
// deprecated warning
@@ -296,9 +292,9 @@ export class NavController extends Ion {
let promise = new Promise(res => { resolve = res; });
// start the transition, fire resolve when done...
- this._transition(enteringView, leavingView, opts, () => {
+ this._transition(enteringView, leavingView, opts, (hasCompleted: boolean) => {
// transition has completed!!
- resolve(enteringView);
+ resolve(hasCompleted);
});
return promise;
@@ -307,7 +303,7 @@ export class NavController extends Ion {
/**
* @private
*/
- private setViews(components, opts = {}) {
+ private setViews(components, opts: NavOptions = {}) {
console.warn('setViews() deprecated, use setPages() instead');
return this.setPages(components, opts);
}
@@ -377,14 +373,7 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass to transtion
* @returns {Promise} Returns a promise, which resolves when the transition has completed
*/
- push(page: Type,
- params: any={},
- opts: {
- animate?: boolean,
- animation?: string
- direction?: string
- }={}
- ) {
+ push(page: Type, params: any = {}, opts: NavOptions = {}) {
return this.insertPages(-1, [{page: page, params: params}], opts);
}
@@ -413,7 +402,7 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass to transtion
* @returns {Promise} Returns a promise, which resolves when the transition has completed
*/
- present(enteringView: ViewController, opts: any = {}): Promise {
+ present(enteringView: ViewController, opts: NavOptions = {}): Promise {
let rootNav = this.rootNav;
if (rootNav['_tabs']) {
@@ -423,8 +412,9 @@ export class NavController extends Ion {
return;
}
+ enteringView.setNav(rootNav);
+
opts.keyboardClose = false;
- opts.skipCache = true;
opts.direction = 'forward';
if (!opts.animation) {
@@ -433,7 +423,6 @@ export class NavController extends Ion {
enteringView.setLeavingOpts({
keyboardClose: false,
- skipCache: true,
direction: 'back',
animation: enteringView.getTransitionName('back')
});
@@ -465,7 +454,7 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass to transtion
* @returns {Promise} Returns a promise when the page has been inserted into the navigation stack
*/
- insert(insertIndex: number, page: Type, params: any = {}, opts: any = {}): Promise {
+ insert(insertIndex: number, page: Type, params: any = {}, opts: NavOptions = {}): Promise {
return this.insertPages(insertIndex, [{page: page, params: params}], opts);
}
@@ -493,16 +482,16 @@ export class NavController extends Ion {
* in and become the active page.
*
* @param {number} insertIndex The index where you want to insert the page
- * @param {Array<{page: Type, params=: any}>} insertPages An array of objects, each with a `page` and optionally `params` property
+ * @param {array<{page: Type, params=: any}>} insertPages An array of objects, each with a `page` and optionally `params` property
* @param {object} [opts={}] Any options you want to use pass to transtion
* @returns {Promise} Returns a promise when the pages have been inserted into the navigation stack
*/
- insertPages(insertIndex: number, insertPages: Array<{page: Type, params?: any}>, opts: any = {}): Promise {
+ insertPages(insertIndex: number, insertPages: Array<{page: Type, params?: any}>, opts: NavOptions = {}): Promise {
let views = insertPages.map(p => new ViewController(p.page, p.params));
return this._insertViews(insertIndex, views, opts);
}
- private _insertViews(insertIndex: number, insertViews: Array, opts: any = {}): Promise {
+ private _insertViews(insertIndex: number, insertViews: Array, opts: NavOptions = {}): Promise {
if (!insertViews || !insertViews.length) {
return Promise.reject('invalid pages');
}
@@ -526,7 +515,7 @@ export class NavController extends Ion {
// transition in, but was simply inserted somewhere in the stack
// go backwards through the stack and find the first active view
// which could be active or one ready to enter
- for (let i = this._views.length - 1; i >= 0; i--) {
+ for (var i = this._views.length - 1; i >= 0; i--) {
if (this._views[i].state === STATE_ACTIVE || this._views[i].state === STATE_INIT_ENTER) {
// found the view at the end of the stack that's either
// already active or it is about to enter
@@ -540,9 +529,9 @@ export class NavController extends Ion {
let leavingView = this.getByState(STATE_INIT_LEAVE);
// start the transition, fire resolve when done...
- this._transition(enteringView, leavingView, opts, () => {
+ this._transition(enteringView, leavingView, opts, (hasCompleted: boolean) => {
// transition has completed!!
- resolve(enteringView);
+ resolve(hasCompleted);
});
return promise;
@@ -627,7 +616,7 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass to transtion
* @returns {Promise} Returns a promise when the transition is completed
*/
- pop(opts: any = {}): Promise {
+ pop(opts: NavOptions = {}): Promise {
// get the index of the active view
// which will become the view to be leaving
let activeView = this.getByState(STATE_TRANS_ENTER) ||
@@ -640,7 +629,7 @@ export class NavController extends Ion {
* Similar to `pop()`, this method let's you navigate back to the root of the stack, no matter how many views that is
* @param {object} [opts={}] Any options you want to use pass to transtion
*/
- popToRoot(opts = {}): Promise {
+ popToRoot(opts: NavOptions = {}): Promise {
return this.popTo(this.first(), opts);
}
@@ -649,7 +638,7 @@ export class NavController extends Ion {
* @param {ViewController} view to pop to
* @param {object} [opts={}] Any options you want to use pass to transtion
*/
- popTo(view: ViewController, opts: any = {}): Promise {
+ popTo(view: ViewController, opts: NavOptions = {}): Promise {
let startIndex = this.indexOf(view);
let activeView = this.getByState(STATE_TRANS_ENTER) ||
this.getByState(STATE_INIT_ENTER) ||
@@ -678,7 +667,7 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass to transtion.
* @returns {Promise} Returns a promise when the page has been removed.
*/
- remove(startIndex: number = -1, removeCount: number = 1, opts: any = {}): Promise {
+ remove(startIndex: number = -1, removeCount: number = 1, opts: NavOptions = {}): Promise {
if (startIndex === -1) {
startIndex = this._views.length - 1;
@@ -704,18 +693,21 @@ export class NavController extends Ion {
opts.animation = forcedActive.getTransitionName(opts.direction);
}
- if (this._lastTrans) {
- this._lastTrans.playbackRate(100).onFinish(() => {
- opts.animate = false;
- this._transition(forcedActive, null, opts, () => {
- // transition has completed!!
- resolve();
- });
- });
- this._lastTrans = null;
+ if (this._trans) {
+ this._trans
+ .onFinish(() => {
+ opts.animate = false;
+ this._transition(forcedActive, null, opts, (hasCompleted: boolean) => {
+ // transition has completed!!
+ resolve(hasCompleted);
+ });
+ }, false, true)
+ .stop();
+ this._trans.destroy();
+ this._trans = null;
} else {
- resolve();
+ resolve(false);
}
return promise;
@@ -736,9 +728,9 @@ export class NavController extends Ion {
let enteringView = this.getByState(STATE_INIT_ENTER);
// start the transition, fire resolve when done...
- this._transition(enteringView, leavingView, opts, () => {
+ this._transition(enteringView, leavingView, opts, (hasCompleted: boolean) => {
// transition has completed!!
- resolve();
+ resolve(hasCompleted);
});
return promise;
@@ -748,7 +740,7 @@ export class NavController extends Ion {
// there's still an active view after _remove() figured out states
// so this means views that were only removed before the active
// view, so auto-resolve since no transition needs to happen
- return Promise.resolve();
+ return Promise.resolve(false);
}
/**
@@ -761,7 +753,7 @@ export class NavController extends Ion {
let view: ViewController = null;
// loop through each view that is set to be removed
- for (let i = startIndex, ii = removeCount + startIndex; i < ii; i++) {
+ for (var i = startIndex, ii = removeCount + startIndex; i < ii; i++) {
view = this.getByIndex(i);
if (!view) break;
@@ -792,7 +784,7 @@ export class NavController extends Ion {
// from the index of the leaving view, go backwards and
// find the first view that is inactive
- for (let i = this.indexOf(view) - 1; i >= 0; i--) {
+ for (var i = this.indexOf(view) - 1; i >= 0; i--) {
if (this._views[i].state === STATE_INACTIVE) {
this._views[i].state = STATE_INIT_ENTER;
break;
@@ -813,7 +805,7 @@ export class NavController extends Ion {
// from the index of the leaving view, go backwards and
// find the first view that is inactive so it can be the entering
- for (let i = this.indexOf(view) - 1; i >= 0; i--) {
+ for (var i = this.indexOf(view) - 1; i >= 0; i--) {
if (this._views[i].state === STATE_INACTIVE) {
this._views[i].state = STATE_INIT_ENTER;
break;
@@ -855,13 +847,13 @@ export class NavController extends Ion {
/**
* @private
*/
- private _transition(enteringView: ViewController, leavingView: ViewController, opts, done: Function) {
+ private _transition(enteringView: ViewController, leavingView: ViewController, opts: NavOptions, done: Function) {
let transId = ++this._transIds;
if (enteringView === leavingView) {
// if the entering view and leaving view are the same thing don't continue
- this._transComplete(transId, enteringView, leavingView, null);
- return done(enteringView);
+ this._transFinish(transId, enteringView, leavingView, null, false);
+ return done(false);
}
// lets time this sucker, ready go
@@ -892,17 +884,17 @@ export class NavController extends Ion {
*/
// begin the multiple async process of transitioning to the entering view
- this._render(transId, enteringView, leavingView, opts, () => {
- this._transComplete(transId, enteringView, leavingView, opts.direction);
+ this._render(transId, enteringView, leavingView, opts, (hasCompleted: boolean) => {
+ this._transFinish(transId, enteringView, leavingView, opts.direction, hasCompleted);
wtfEndTimeRange(wtfScope);
- done(enteringView);
+ done(hasCompleted);
});
}
/**
* @private
*/
- private _render(transId, enteringView: ViewController, leavingView: ViewController, opts: any, done: Function) {
+ private _render(transId, enteringView: ViewController, leavingView: ViewController, opts: NavOptions, done: Function) {
// compile/load the view into the DOM
if (enteringView.state === STATE_INACTIVE) {
@@ -948,7 +940,7 @@ export class NavController extends Ion {
/**
* @private
*/
- private _postRender(transId, enteringView: ViewController, leavingView: ViewController, isAlreadyTransitioning: boolean, opts: any, done: Function) {
+ private _postRender(transId, enteringView: ViewController, leavingView: ViewController, isAlreadyTransitioning: boolean, opts: NavOptions, done: Function) {
// called after _render has completed and the view is compiled/loaded
if (enteringView.state === STATE_INACTIVE) {
@@ -989,25 +981,19 @@ export class NavController extends Ion {
enteringView.willEnter();
leavingView.willLeave();
- // lifecycle events may have updated some data
- // wait one frame and allow the raf to do a change detection
- // before kicking off the transition and showing the new view
- raf(() => {
- this._beforeTrans(enteringView, leavingView, opts, done);
- });
-
} else {
// this view is being preloaded, don't call lifecycle events
// transition does not need to animate
opts.animate = false;
- this._beforeTrans(enteringView, leavingView, opts, done);
}
+
+ this._beforeTrans(enteringView, leavingView, opts, done);
}
/**
* @private
*/
- private _beforeTrans(enteringView: ViewController, leavingView: ViewController, opts: any, done: Function) {
+ private _beforeTrans(enteringView: ViewController, leavingView: ViewController, opts: NavOptions, done: Function) {
// called after one raf from postRender()
// create the transitions animation, play the animation
// when the transition ends call wait for it to end
@@ -1025,16 +1011,21 @@ export class NavController extends Ion {
this._zone.runOutsideAngular(() => {
// init the transition animation
- opts.renderDelay = opts.transitionDelay || this._trnsDelay;
+ let transitionOpts = {
+ animation: opts.animation,
+ direction: opts.direction,
+ duration: opts.duration,
+ easing: opts.easing,
+ renderDelay: opts.transitionDelay || this._trnsDelay,
+ isRTL: this.config.platform.isRTL()
+ };
- // set if this app is right-to-left or not
- opts.isRTL = this.config.platform.isRTL();
+ let transAnimation = Transition.createTransition(enteringView,
+ leavingView,
+ transitionOpts);
- let transAnimation = Animation.createTransition(enteringView,
- leavingView,
- opts);
-
- this._lastTrans = transAnimation;
+ this._trans && this._trans.destroy();
+ this._trans = transAnimation;
if (opts.animate === false) {
// force it to not animate the elements, just apply the "to" styles
@@ -1053,24 +1044,34 @@ export class NavController extends Ion {
}
// create a callback for when the animation is done
- transAnimation.onFinish(() => {
+ transAnimation.onFinish((hasCompleted: boolean) => {
// transition animation has ended
- // dispose the animation and it's element references
+ // destroy the animation and it's element references
transAnimation.destroy();
- this._afterTrans(enteringView, leavingView, opts, done);
+ this._afterTrans(enteringView, leavingView, opts, hasCompleted, done);
});
// cool, let's do this, start the transition
- transAnimation.play();
+ if (opts.progressAnimation) {
+ // this is a swipe to go back, just get the transition progress ready
+ // kick off the swipe animation start
+ transAnimation.progressStart();
+
+ } else {
+
+ // this is a normal animation
+ // kick it off and let it play through
+ transAnimation.play();
+ }
});
}
/**
* @private
*/
- private _afterTrans(enteringView: ViewController, leavingView: ViewController, opts: any, done: Function) {
+ private _afterTrans(enteringView: ViewController, leavingView: ViewController, opts: NavOptions, hasCompleted: boolean, done: Function) {
// transition has completed, update each view's state
// place back into the zone, run didEnter/didLeave
// call the final callback when done
@@ -1078,7 +1079,7 @@ export class NavController extends Ion {
// run inside of the zone again
this._zone.run(() => {
- if (!opts.preload) {
+ if (!opts.preload && hasCompleted) {
enteringView.didEnter();
leavingView.didLeave();
}
@@ -1086,7 +1087,7 @@ export class NavController extends Ion {
if (enteringView.state === STATE_INACTIVE) {
// this entering view is already set to inactive, so this
// transition must be canceled, so don't continue
- return done();
+ return done(hasCompleted);
}
if (opts.keyboardClose !== false && this._keyboard.isOpen()) {
@@ -1096,12 +1097,12 @@ export class NavController extends Ion {
this._keyboard.onClose(() => {
// keyboard has finished closing, transition complete
- done();
+ done(hasCompleted);
}, 32);
} else {
// all good, transition complete
- done();
+ done(hasCompleted);
}
});
}
@@ -1109,51 +1110,67 @@ export class NavController extends Ion {
/**
* @private
*/
- private _transComplete(transId: number, enteringView: ViewController, leavingView: ViewController, direction: string) {
+ private _transFinish(transId: number, enteringView: ViewController, leavingView: ViewController, direction: string, hasCompleted: boolean) {
// a transition has completed, but not sure if it's the last one or not
// check if this transition is the most recent one or not
if (transId === this._transIds) {
// ok, good news, there were no other transitions that kicked
// off during the time this transition started and ended
- // so the entering one is now officially the active transition
- // and the leaving transition is now just inactive
- if (enteringView.state !== STATE_REMOVE_AFTER_TRANS) {
- enteringView.state = STATE_ACTIVE;
- }
+ if (hasCompleted) {
+ // this transition has completed as normal
+ // so the entering one is now the active view
+ // and the leaving view is now just inactive
+ if (enteringView.state !== STATE_REMOVE_AFTER_TRANS) {
+ enteringView.state = STATE_ACTIVE;
+ }
+ if (leavingView.state !== STATE_REMOVE_AFTER_TRANS) {
+ leavingView.state = STATE_INACTIVE;
+ }
- if (leavingView.state !== STATE_REMOVE_AFTER_TRANS) {
- leavingView.state = STATE_INACTIVE;
- }
+ // only need to do all this clean up if the transition
+ // completed, otherwise nothing actually changed
+ // destroy all of the views that come after the active view
+ this._cleanup();
- // destroy all of the views that come after the active view
- this._cleanup();
+ // make sure only this entering view and PREVIOUS view are the
+ // only two views that are not display:none
+ leavingView = this.getPrevious(enteringView);
+ this._views.forEach(view => {
+ let shouldShow = (view === enteringView) || (view === leavingView);
+ view.domCache(shouldShow, this._renderer);
+ });
- // make sure only this entering view and PREVIOUS view are the
- // only two views that are not display:none
- leavingView = this.getPrevious(enteringView);
- this._views.forEach(view => {
- let shouldShow = (view === enteringView) || (view === leavingView);
- view.domCache(shouldShow, this._renderer);
- });
+ // this check only needs to happen once, which will add the css
+ // class to the nav when it's finished its first transition
+ if (!this._init) {
+ this._init = true;
+ this._renderer.setElementClass(this.elementRef.nativeElement, 'has-views', true);
+ }
- // this check only needs to happen once, which will add the css
- // class to the nav when it's finished its first transition
- if (!this._init) {
- this._init = true;
- this._renderer.setElementClass(this.elementRef.nativeElement, 'has-views', true);
+ } else {
+ // this transition has not completed, meaning the
+ // entering view did not end up as the active view
+ // this would happen when swipe to go back started
+ // but the user did not complete the swipe and the
+ // what was the active view stayed as the active view
+ leavingView.state = STATE_ACTIVE;
+ enteringView.state = STATE_INACTIVE;
}
// allow clicks and enable the app again
this._app && this._app.setEnabled(true);
this.setTransitioning(false);
- if (this.router && direction !== null) {
+ if (this.router && direction !== null && hasCompleted) {
// notify router of the state change if a direction was provided
this.router.stateChange(direction, enteringView);
}
+ // see if we should add the swipe back gesture listeners or not
+ this._sbCheck();
+
} else {
// darn, so this wasn't the most recent transition
// so while this one did end, there's another more recent one
@@ -1176,7 +1193,7 @@ export class NavController extends Ion {
let activeViewIndex = this.indexOf(this.getActive());
let destroys = this._views.filter(v => v.state === STATE_REMOVE_AFTER_TRANS);
- for (let i = activeViewIndex + 1; i < this._views.length; i++) {
+ for (var i = activeViewIndex + 1; i < this._views.length; i++) {
if (this._views[i].state === STATE_INACTIVE) {
destroys.push(this._views[i]);
}
@@ -1188,12 +1205,13 @@ export class NavController extends Ion {
this._views.splice(this.indexOf(view), 1);
view.destroy();
});
+
}
/**
* @private
*/
- loadPage(view: ViewController, navbarContainerRef, opts: any, done: Function) {
+ loadPage(view: ViewController, navbarContainerRef, opts: NavOptions, done: Function) {
let wtfTimeRangeScope = wtfStartTimeRange('NavController#loadPage', view.name);
// guts of DynamicComponentLoader#loadIntoLocation
@@ -1268,167 +1286,100 @@ export class NavController extends Ion {
* @private
*/
swipeBackStart() {
- return;
- if (!this._app.isEnabled() || !this.canSwipeBack()) {
- return;
- }
-
- // disables the app during the transition
- this._app.setEnabled(false);
- this.setTransitioning(true);
-
// default the direction to "back"
- let opts = {
- direction: 'back'
+ let opts: NavOptions = {
+ direction: 'back',
+ progressAnimation: true
};
- // get the active view and set that it is staged to be leaving
- // was probably the one popped from the stack
- let leavingView = this.getActive() || new ViewController();
- leavingView.willLeave();
- leavingView.willUnload();
+ // figure out the states of each view in the stack
+ let leavingView = this._remove(this._views.length - 1, 1);
- // the entering view is now the new last view
- let enteringView = this.getPrevious(leavingView);
- enteringView.willEnter();
+ if (leavingView) {
+ opts.animation = leavingView.getTransitionName(opts.direction);
- // wait for the new view to complete setup
- this._render(0, enteringView, leavingView, {}, () => {
-
- this._zone.runOutsideAngular(() => {
- // set that the new view pushed on the stack is staged to be entering/leaving
- // staged state is important for the transition to find the correct view
- // enteringView.state = STATE_RENDERED_ENTER;
- // leavingView.state = STATE_RENDERED_LEAVE;
-
- // init the swipe back transition animation
- this._sbTrans = Animation.createTransition(enteringView, leavingView, opts);
- this._sbTrans.easing('linear').progressStart();
+ // get the view thats ready to enter
+ let enteringView = this.getByState(STATE_INIT_ENTER);
+ // start the transition, fire callback when done...
+ this._transition(enteringView, leavingView, opts, (hasCompleted: boolean) => {
+ // swipe back has finished!!
+ console.debug('swipeBack, hasCompleted', hasCompleted);
});
- });
-
+ }
}
/**
* @private
*/
- swipeBackProgress(value) {
- return;
- if (this._sbTrans) {
+ swipeBackProgress(stepValue: number) {
+ if (this._trans && this._sbGesture) {
// continue to disable the app while actively dragging
this._app.setEnabled(false, 4000);
this.setTransitioning(true, 4000);
// set the transition animation's progress
- this._sbTrans.progress(value);
+ this._trans.progressStep(stepValue);
}
}
/**
* @private
*/
- swipeBackEnd(completeSwipeBack, rate) {
- return;
- if (!this._sbTrans) return;
-
- // disables the app during the transition
- this._app.setEnabled(false);
- this.setTransitioning(true);
-
- this._sbTrans.progressEnd(completeSwipeBack, rate).then(() => {
-
- this._zone.run(() => {
- // find the views that were entering and leaving
- let enteringView = null;// this._getStagedEntering();
- let leavingView = null;//this._getStagedLeaving();
-
- if (enteringView && leavingView) {
- // finish up the animation
-
- if (completeSwipeBack) {
- // swipe back has completed navigating back
- // update each view's state
- enteringView.state = STATE_ACTIVE;
- leavingView.state = STATE_INACTIVE;
-
- enteringView.didEnter();
- leavingView.didLeave();
-
- if (this.router) {
- // notify router of the pop state change
- this.router.stateChange('pop', enteringView);
- }
-
- } else {
- // cancelled the swipe back, they didn't end up going back
- // return views to their original state
- leavingView.state = STATE_ACTIVE;
- enteringView.state = STATE_INACTIVE;
-
- leavingView.willEnter();
- leavingView.didEnter();
- enteringView.didLeave();
-
- leavingView.shouldDestroy = false;
- enteringView.shouldDestroy = false;
- }
- }
-
- // empty out and dispose the swipe back transition animation
- this._sbTrans && this._sbTrans.dispose();
- this._sbTrans = null;
-
- // all done!
- //this._transComplete();
- });
- });
-
+ swipeBackEnd(shouldComplete: boolean, currentStepValue: number) {
+ if (this._trans && this._sbGesture) {
+ // the swipe back gesture has ended
+ this._trans.progressEnd(shouldComplete, currentStepValue);
+ }
}
/**
* @private
*/
- private _sbComplete() {
- return;
- if (this.canSwipeBack()) {
- // it is possible to swipe back
+ private _sbCheck() {
+ if (this._sbEnabled) {
+ // this nav controller can have swipe to go back
- if (this.sbGesture) {
- // this is already an active gesture, don't create another one
- return;
+ if (!this._sbGesture) {
+ // create the swipe back gesture if we haven't already
+ let opts = {
+ edge: 'left',
+ threshold: this._sbThreshold
+ };
+ this._sbGesture = new SwipeBackGesture(this.getNativeElement(), opts, this);
}
- let opts = {
- edge: 'left',
- threshold: this._sbThreshold
- };
- this.sbGesture = new SwipeBackGesture(this.getNativeElement(), opts, this);
- console.debug('SwipeBackGesture listen');
- this.sbGesture.listen();
+ if (this.canSwipeBack()) {
+ // it is be possible to swipe back
+ if (!this._sbGesture.isListening) {
+ this._zone.runOutsideAngular(() => {
+ // start listening if it's not already
+ console.debug('swipeBack gesture, listen');
+ this._sbGesture.listen();
+ });
+ }
-
- } else if (this.sbGesture) {
- // it is not possible to swipe back and there is an
- // active sbGesture, so unlisten it
- console.debug('SwipeBackGesture unlisten');
- this.sbGesture.unlisten();
- this.sbGesture = null;
+ } else if (this._sbGesture.isListening) {
+ // it should not be possible to swipe back
+ // but the gesture is still listening
+ console.debug('swipeBack gesture, unlisten');
+ this._sbGesture.unlisten();
+ }
}
}
/**
- * Check to see if swipe-to-go-back is enabled
- * @param {boolean} isSwipeBackEnabled Set whether or not swipe-to-go-back is enabled
- * @returns {boolean} Whether swipe-to-go-back is enabled
+ * @input {boolean} Whether it's possible to swipe-to-go-back on this nav controller or not.
*/
- isSwipeBackEnabled(val?: boolean): boolean {
- if (arguments.length) {
- this._sbEnabled = !!val;
- }
+ @Input()
+ get swipeBackEnabled(): boolean {
return this._sbEnabled;
}
+ set swipeBackEnabled(val: boolean) {
+ this._sbEnabled = isTrueProperty(val);
+ }
+
/**
* If it's possible to use swipe back or not. If it's not possible
* to go back, or swipe back is not enable then this will return false.
@@ -1437,7 +1388,7 @@ export class NavController extends Ion {
* @returns {boolean} Whether you can swipe to go back
*/
canSwipeBack(): boolean {
- return (this._sbEnabled && this.canGoBack());
+ return (this._sbEnabled && !this.isTransitioning() && this._app.isEnabled() && this.canGoBack());
}
/**
@@ -1475,7 +1426,7 @@ export class NavController extends Ion {
* @returns {ViewController}
*/
getByState(state: string): ViewController {
- for (let i = this._views.length - 1; i >= 0; i--) {
+ for (var i = this._views.length - 1; i >= 0; i--) {
if (this._views[i].state === state) {
return this._views[i];
}
@@ -1508,7 +1459,7 @@ export class NavController extends Ion {
/**
* @param {ViewController} view The ViewController to get the previous view to
- * @returns {ViewController}
+ * @returns {viewController}
*/
getPrevious(view: ViewController): ViewController {
return this.getByIndex( this.indexOf(view) - 1 );
@@ -1595,6 +1546,19 @@ export class NavController extends Ion {
}
+export interface NavOptions {
+ animate?: boolean;
+ animation?: string;
+ direction?: string;
+ duration?: number;
+ easing?: string;
+ keyboardClose?: boolean;
+ preload?: boolean;
+ transitionDelay?: number;
+ postLoad?: Function;
+ progressAnimation?: boolean;
+}
+
const STATE_ACTIVE = 'active';
const STATE_INACTIVE = 'inactive';
const STATE_INIT_ENTER = 'init_enter';
diff --git a/ionic/components/nav/nav-push.ts b/ionic/components/nav/nav-push.ts
index 8a18e821e3..7fc327832f 100644
--- a/ionic/components/nav/nav-push.ts
+++ b/ionic/components/nav/nav-push.ts
@@ -50,7 +50,15 @@ import {NavRegistry} from './nav-registry';
}
})
export class NavPush {
+
+ /**
+ * @input {page} the page you want to push
+ */
@Input() navPush;
+
+ /**
+ * @input {any} Any parameters you want to pass along
+ */
@Input() navParams;
constructor(
diff --git a/ionic/components/nav/nav.ts b/ionic/components/nav/nav.ts
index 0d9f3727e8..1a11bf757b 100644
--- a/ionic/components/nav/nav.ts
+++ b/ionic/components/nav/nav.ts
@@ -1,4 +1,4 @@
-import {Component, ElementRef, Input, Optional, NgZone, Compiler, AppViewManager, Renderer, Type, ViewChild} from 'angular2/core';
+import {Component, ElementRef, Input, Optional, NgZone, Compiler, AppViewManager, Renderer, Type} from 'angular2/core';
import {IonicApp} from '../app/app';
import {Config} from '../../config/config';
@@ -98,7 +98,7 @@ import {ViewController} from './view-controller';
*
*
*
- * @demo /docs/v2/demos/navigation/
+ * @demo /docs/v2/demos/navigation/
* @see {@link /docs/v2/components#navigation Navigation Component Docs}
*/
@Component({
@@ -112,11 +112,6 @@ export class Nav extends NavController {
*/
@Input() root: Type;
- /**
- * @private
- */
- @Input() swipeBackEnabled: any;
-
constructor(
@Optional() hostNavCtrl: NavController,
@Optional() viewCtrl: ViewController,
@@ -149,9 +144,6 @@ export class Nav extends NavController {
}
this.push(this.root);
}
-
- // default the swipe back to be enabled
- this.isSwipeBackEnabled( (this.swipeBackEnabled || '').toString() !== 'false' );
}
}
diff --git a/ionic/components/nav/swipe-back.ts b/ionic/components/nav/swipe-back.ts
index 9c90494ef1..ed26de85b4 100644
--- a/ionic/components/nav/swipe-back.ts
+++ b/ionic/components/nav/swipe-back.ts
@@ -1,36 +1,57 @@
import {NavController} from './nav-controller';
import {SlideEdgeGesture} from '../../gestures/slide-edge-gesture';
+import {SlideData} from '../../gestures/slide-gesture';
+import {assign} from '../../util/util';
export class SwipeBackGesture extends SlideEdgeGesture {
- public edges: Array;
- public threshold: string;
constructor(
- element: HTMLElement,
- opts: any = {},
+ element: HTMLElement,
+ options: any,
private _nav: NavController
) {
- super(element, opts);
-
- // Can check corners through use of eg 'left top'
- this.edges = opts.edge.split(' ');
- this.threshold = opts.threshold;
+ super(element, assign({
+ direction: 'x',
+ maxEdgeStart: 75
+ }, options));
}
- onSlideStart() {
+ canStart(ev: any) {
+ // the gesture swipe angle must be mainly horizontal and the
+ // gesture distance would be relatively short for a swipe back
+ // and swipe back must be possible on this nav controller
+ if (ev.angle > -40 &&
+ ev.angle < 40 &&
+ ev.distance < 50 &&
+ this._nav.canSwipeBack()) {
+ // passed the tests, now see if the super says it's cool or not
+ return super.canStart(ev);
+ }
+
+ // nerp, not today
+ return false;
+ }
+
+ onSlideBeforeStart() {
+ console.debug('swipeBack, onSlideBeforeStart');
this._nav.swipeBackStart();
}
- onSlide(slide, ev) {
- this._nav.swipeBackProgress(slide.distance / slide.max);
+ onSlide(slide: SlideData) {
+ let stepValue = (slide.distance / slide.max);
+ console.debug('swipeBack, onSlide, distance', slide.distance, 'max', slide.max, 'stepValue', stepValue);
+ this._nav.swipeBackProgress(stepValue);
}
- onSlideEnd(slide, ev) {
+ onSlideEnd(slide: SlideData, ev: any) {
let shouldComplete = (Math.abs(ev.velocityX) > 0.2 || Math.abs(slide.delta) > Math.abs(slide.max) * 0.5);
- // TODO: calculate a better playback rate depending on velocity and distance
- this._nav.swipeBackEnd(shouldComplete, 1);
+ let currentStepValue = (slide.distance / slide.max);
+
+ console.debug('swipeBack, onSlideEnd, shouldComplete', shouldComplete, 'currentStepValue', currentStepValue);
+
+ this._nav.swipeBackEnd(shouldComplete, currentStepValue);
}
}
diff --git a/ionic/components/nav/test/basic/index.ts b/ionic/components/nav/test/basic/index.ts
index c45476d72a..cad35e3432 100644
--- a/ionic/components/nav/test/basic/index.ts
+++ b/ionic/components/nav/test/basic/index.ts
@@ -1,7 +1,7 @@
import {Component, Type} from 'angular2/core';
-import {App, NavController, Alert} from 'ionic/ionic';
-import {Page, Config, IonicApp} from 'ionic/ionic';
-import {NavParams, ViewController, IONIC_DIRECTIVES} from 'ionic/ionic';
+import {App, NavController, Alert} from '../../../../../ionic/ionic';
+import {Page, Config, IonicApp} from '../../../../../ionic/ionic';
+import {NavParams, ViewController, IONIC_DIRECTIVES} from '../../../../../ionic/ionic';;
@Component({
@@ -20,7 +20,7 @@ class MyCmpTest{}
- S1
+ S1g
@@ -74,7 +74,7 @@ class FirstPage {
setPages() {
let items = [
- {page: PrimaryHeaderPage}
+ { page: PrimaryHeaderPage }
];
this.nav.setPages(items);
@@ -89,7 +89,7 @@ class FirstPage {
}
pushFullPage() {
- this.nav.push(FullPage, { id: 8675309, myData: [1,2,3,4] } );
+ this.nav.push(FullPage, { id: 8675309, myData: [1, 2, 3, 4] });
}
pushAnother() {
@@ -139,8 +139,8 @@ class FullPage {
setPages() {
let items = [
- {page: FirstPage},
- {page: PrimaryHeaderPage}
+ { page: FirstPage },
+ { page: PrimaryHeaderPage }
];
this.nav.setPages(items);
@@ -190,6 +190,9 @@ class FullPage {
template: `
Primary Color Page Header
+
+ S1g
+
Pop
@@ -218,7 +221,7 @@ class PrimaryHeaderPage {
}
pushFullPage() {
- this.nav.push(FullPage, { id: 8675309, myData: [1,2,3,4] } );
+ this.nav.push(FullPage, { id: 8675309, myData: [1, 2, 3, 4] });
}
insert() {
diff --git a/ionic/components/nav/test/insert-views/index.ts b/ionic/components/nav/test/insert-views/index.ts
index eabc724299..168e348d2a 100644
--- a/ionic/components/nav/test/insert-views/index.ts
+++ b/ionic/components/nav/test/insert-views/index.ts
@@ -1,4 +1,4 @@
-import {App, Page, NavController} from 'ionic/ionic';
+import {App, Page, NavController} from '../../../../../ionic/ionic';
@@ -9,14 +9,14 @@ import {App, Page, NavController} from 'ionic/ionic';
- Push Page
+ Push Page
`,
})
class FirstPage {
constructor(nav: NavController) {
this.nav = nav;
}
- pushPage(){
+ pushPage() {
this.nav.push(SecondPage)
}
}
@@ -30,7 +30,7 @@ class FirstPage {
Second page
- Insert Page
+ Insert Page
`
})
@@ -38,7 +38,7 @@ class SecondPage {
constructor(nav: NavController) {
this.nav = nav;
}
- insertPage(){
+ insertPage() {
this.nav.insert(1, InsertPage)
}
}
@@ -55,7 +55,7 @@ class SecondPage {
`
})
class InsertPage {
- constructor() {}
+ constructor() { }
}
diff --git a/ionic/components/nav/test/nav-controller.spec.ts b/ionic/components/nav/test/nav-controller.spec.ts
index e842e22a5c..db99a97c7d 100644
--- a/ionic/components/nav/test/nav-controller.spec.ts
+++ b/ionic/components/nav/test/nav-controller.spec.ts
@@ -1,4 +1,4 @@
-import {NavController, Config, ViewController} from 'ionic/ionic';
+import {NavController, Config, ViewController} from '../../../../ionic/ionic';
export function run() {
describe('NavController', () => {
@@ -291,7 +291,7 @@ export function run() {
});
});
- describe('_transComplete', () => {
+ describe('_transFinish', () => {
it('should not entering/leaving state, after transition that isnt the most recent, and state already changed', () => {
let enteringView = new ViewController(Page1);
@@ -301,7 +301,7 @@ export function run() {
nav._transIds = 2;
- nav._transComplete(1, enteringView, leavingView);
+ nav._transFinish(1, enteringView, leavingView, 'forward', true);
expect(enteringView.state).toBe('somethingelse');
expect(leavingView.state).toBe('somethingelse');
@@ -315,7 +315,7 @@ export function run() {
nav._transIds = 2;
- nav._transComplete(1, enteringView, leavingView);
+ nav._transFinish(1, enteringView, leavingView, 'forward', true);
expect(enteringView.state).toBe(STATE_INACTIVE);
expect(leavingView.state).toBe(STATE_INACTIVE);
@@ -329,12 +329,26 @@ export function run() {
nav._transIds = 1;
- nav._transComplete(1, enteringView, leavingView);
+ nav._transFinish(1, enteringView, leavingView, 'forward', true);
expect(enteringView.state).toBe(STATE_ACTIVE);
expect(leavingView.state).toBe(STATE_INACTIVE);
});
+ it('should set entering inactive, leaving active, after transition has not completed', () => {
+ let enteringView = new ViewController(Page1);
+ enteringView.state = STATE_TRANS_ENTER;
+ let leavingView = new ViewController(Page2);
+ leavingView.state = STATE_TRANS_LEAVE;
+
+ nav._transIds = 1;
+
+ nav._transFinish(1, enteringView, leavingView, 'back', false);
+
+ expect(enteringView.state).toBe(STATE_INACTIVE);
+ expect(leavingView.state).toBe(STATE_ACTIVE);
+ });
+
});
describe('_insert', () => {
@@ -541,7 +555,7 @@ export function run() {
});
it('should getByState()', () => {
- expect(nav.getByState()).toBe(null);
+ expect(nav.getByState(null)).toBe(null);
let view1 = new ViewController(Page1);
view1.state = STATE_INIT_ENTER;
@@ -618,7 +632,7 @@ export function run() {
});
// setup stuff
- let nav;
+ let nav: NavController;
let config = new Config();
class Page1 {}
diff --git a/ionic/components/nav/test/nested/index.ts b/ionic/components/nav/test/nested/index.ts
index 68f6f4ff45..3339ea7e3a 100644
--- a/ionic/components/nav/test/nested/index.ts
+++ b/ionic/components/nav/test/nested/index.ts
@@ -1,5 +1,5 @@
-import {App, NavParams, NavController, ViewController, MenuController} from 'ionic/ionic';
-import {Page, Config, IonicApp} from 'ionic/ionic';
+import {App, NavParams, NavController, ViewController, MenuController} from '../../../../../ionic/ionic';
+import {Page, Config, IonicApp} from '../../../../../ionic/ionic';
@Page({
diff --git a/ionic/components/nav/test/routing/index.ts b/ionic/components/nav/test/routing/index.ts
index 2ed275e313..45c0b14278 100644
--- a/ionic/components/nav/test/routing/index.ts
+++ b/ionic/components/nav/test/routing/index.ts
@@ -1,6 +1,6 @@
import {RouteConfig, Location} from 'angular2/router';
-import {App, Page, NavParams, ViewController} from 'ionic/ionic';
+import {App, Page, NavParams, ViewController} from '../../../../../ionic/ionic';
@Page({templateUrl: 'view1.html'})
diff --git a/ionic/components/nav/view-controller.ts b/ionic/components/nav/view-controller.ts
index 1cabd98ff8..d2ca968d56 100644
--- a/ionic/components/nav/view-controller.ts
+++ b/ionic/components/nav/view-controller.ts
@@ -1,7 +1,7 @@
import {Output, EventEmitter, Type, TemplateRef, ViewContainerRef, ElementRef, Renderer} from 'angular2/core';
import {Navbar} from '../navbar/navbar';
-import {NavController} from './nav-controller';
+import {NavController, NavOptions} from './nav-controller';
import {NavParams} from './nav-params';
@@ -21,11 +21,11 @@ import {NavParams} from './nav-params';
* ```
*/
export class ViewController {
- private _cntDir;
+ private _cntDir: any;
private _cntRef: ElementRef;
private _destroys: Array = [];
- private _hdAttr = null;
- private _leavingOpts = null;
+ private _hdAttr: string = null;
+ private _leavingOpts: NavOptions = null;
private _loaded: boolean = false;
private _nbDir: Navbar;
private _nbTmpRef: TemplateRef;
@@ -34,6 +34,11 @@ export class ViewController {
private _pgRef: ElementRef;
protected _nav: NavController;
+ /**
+ * @private
+ */
+ data: any;
+
/**
* @private
*/
@@ -57,33 +62,39 @@ export class ViewController {
/**
* @private
*/
- onReady: any;
+ onReady: Function;
/**
* @private
*/
zIndex: number;
+ /**
+ * @private
+ */
@Output() private _emitter: EventEmitter = new EventEmitter();
- constructor(public componentType?: Type, public data: any = {}) {}
+ constructor(public componentType?: Type, data: any = {}) {
+ // passed in data could be NavParams, but all we care about is its data object
+ this.data = (data instanceof NavParams ? data.data : data);
+ }
- subscribe(callback) {
- this._emitter.subscribe(callback);
+ subscribe(generatorOrNext?: any): any {
+ return this._emitter.subscribe(generatorOrNext);
}
/**
* @private
*/
- emit(data) {
+ emit(data: any) {
this._emitter.emit(data);
}
- onDismiss(callback) {
+ onDismiss(callback: Function) {
this._onDismiss = callback;
}
- dismiss(data, role?) {
+ dismiss(data: any, role?: any) {
this._onDismiss && this._onDismiss(data, role);
return this._nav.remove(this._nav.indexOf(this), 1, this._leavingOpts);
}
@@ -91,28 +102,28 @@ export class ViewController {
/**
* @private
*/
- setNav(navCtrl) {
+ setNav(navCtrl: NavController) {
this._nav = navCtrl;
}
/**
* @private
*/
- getTransitionName(direction) {
+ getTransitionName(direction: string): string {
return this._nav && this._nav.config.get('pageTransition');
}
/**
* @private
*/
- getNavParams() {
+ getNavParams(): NavParams {
return new NavParams(this.data);
}
/**
* @private
*/
- setLeavingOpts(opts) {
+ setLeavingOpts(opts: NavOptions) {
this._leavingOpts = opts;
}
@@ -121,7 +132,7 @@ export class ViewController {
* @param {boolean} Check whether or not you can go back from this page
* @returns {boolean} Returns if it's possible to go back from this Page.
*/
- enableBack() {
+ enableBack(): boolean {
// update if it's possible to go back from this nav item
if (this._nav) {
let previousItem = this._nav.getPrevious(this);
@@ -135,14 +146,14 @@ export class ViewController {
/**
* @private
*/
- setInstance(instance) {
+ setInstance(instance: any) {
this.instance = instance;
}
/**
* @private
*/
- get name() {
+ get name(): string {
return this.componentType ? this.componentType['name'] : '';
}
@@ -183,7 +194,7 @@ export class ViewController {
* @private
*/
destroy() {
- for (let i = 0; i < this._destroys.length; i++) {
+ for (var i = 0; i < this._destroys.length; i++) {
this._destroys[i]();
}
this._destroys = [];
@@ -259,7 +270,7 @@ export class ViewController {
/**
* @private
- * @returns {ElementRef} Returns the Page's ElementRef
+ * @returns {elementRef} Returns the Page's ElementRef
*/
pageRef(): ElementRef {
return this._pgRef;
@@ -274,7 +285,7 @@ export class ViewController {
/**
* @private
- * @returns {ElementRef} Returns the Page's Content ElementRef
+ * @returns {elementRef} Returns the Page's Content ElementRef
*/
contentRef(): ElementRef {
return this._cntRef;
@@ -289,7 +300,7 @@ export class ViewController {
/**
* @private
- * @returns {Component} Returns the Page's Content component reference.
+ * @returns {component} Returns the Page's Content component reference.
*/
getContent() {
return this._cntDir;
diff --git a/ionic/components/navbar/navbar.ts b/ionic/components/navbar/navbar.ts
index eddd5e575d..ea43804530 100644
--- a/ionic/components/navbar/navbar.ts
+++ b/ionic/components/navbar/navbar.ts
@@ -94,9 +94,11 @@ class ToolbarBackground {
template:
'
' +
'' +
- ' ' +
- '' +
- '{{_bbText}} ' +
+ '' +
+ ' ' +
+ '' +
+ '{{_bbText}} ' +
+ ' ' +
' ' +
' ' +
' ' +
diff --git a/ionic/components/option/option.ts b/ionic/components/option/option.ts
index fd8497b0e7..522c254b4c 100644
--- a/ionic/components/option/option.ts
+++ b/ionic/components/option/option.ts
@@ -7,9 +7,6 @@ import {isDefined, isTrueProperty} from '../../util/util';
* @description
* `ion-option` is a child component of `ion-select`. Similar to the native option element, `ion-option` can take a value and a checked property.
*
- * @property [value] - the value of the option
- * @property [checked] - whether or not the option is already checked and selected
- *
* @demo /docs/v2/demos/item-sliding/
*/
@Directive({
@@ -20,14 +17,14 @@ export class Option {
private _value;
/**
- * @private
+ * @input {any} Event to evaluate when option has changed
*/
@Output() select: EventEmitter = new EventEmitter();
constructor(private _elementRef: ElementRef) {}
/**
- * @private
+ * @input {boolean} Whether or not the option is already checked and selected
*/
@Input()
get checked() {
@@ -39,7 +36,7 @@ export class Option {
}
/**
- * @private
+ * @input {any} The value of the option
*/
@Input()
get value() {
diff --git a/ionic/components/radio/radio-button.ts b/ionic/components/radio/radio-button.ts
index 505dcc25e7..539b51b938 100644
--- a/ionic/components/radio/radio-button.ts
+++ b/ionic/components/radio/radio-button.ts
@@ -14,7 +14,7 @@ import {RadioGroup} from './radio-group';
* and there must be at least two `` components within
* the radio group.
*
- * See the [Angular 2 Docs](https://angular.io/docs/js/latest/api/forms/) for
+ * See the [Angular 2 Docs](https://angular.io/docs/ts/latest/guide/forms.html) for
* more info on forms and input.
*
* @usage
@@ -58,7 +58,7 @@ export class RadioButton {
id: string;
/**
- * @private
+ * @output {any} expression to be evaluated when clicked
*/
@Output() select: EventEmitter = new EventEmitter();
@@ -71,7 +71,7 @@ export class RadioButton {
if (_group) {
// register with the radiogroup
- this.id = 'rb-' + _group.register(this);
+ this.id = 'rb-' + _group.add(this);
}
if (_item) {
@@ -105,27 +105,10 @@ export class RadioButton {
}
set checked(isChecked) {
- if (!this._disabled) {
- // only check/uncheck if it's not disabled
+ this._checked = isTrueProperty(isChecked);
- // emit the select event for the radiogroup to catch
- this._checked = isTrueProperty(isChecked);
- this.select.emit(this.value);
-
- // if it's a stand-alone radiobutton nothing else happens
- // if it was within a radiogroup then updateAsChecked will
- // get called again
- this.updateAsChecked(this._checked);
- }
- }
-
- /**
- * @private
- */
- updateAsChecked(val: boolean) {
- this._checked = val;
if (this._item) {
- this._item.setCssClass('item-radio-checked', val);
+ this._item.setCssClass('item-radio-checked', this._checked);
}
}
@@ -150,7 +133,18 @@ export class RadioButton {
console.debug('radio, select', this.id);
ev.preventDefault();
ev.stopPropagation();
+
this.checked = true;
+ this.select.emit(this.value);
+ }
+
+ /**
+ * @private
+ */
+ ngOnInit() {
+ if (this._group && isDefined(this._group.value) && this._group.value === this.value) {
+ this.checked = true;
+ }
}
/**
@@ -158,5 +152,6 @@ export class RadioButton {
*/
ngOnDestroy() {
this._form.deregister(this);
+ this._group.remove(this);
}
}
diff --git a/ionic/components/radio/radio-group.ts b/ionic/components/radio/radio-group.ts
index d51331db21..64c7d2659b 100644
--- a/ionic/components/radio/radio-group.ts
+++ b/ionic/components/radio/radio-group.ts
@@ -1,19 +1,22 @@
-import {Directive, ElementRef, Renderer, Optional, Input, Output, HostListener, ContentChild, EventEmitter} from 'angular2/core';
-import {NgControl} from 'angular2/common';
+import {Directive, ElementRef, Renderer, Optional, Input, Output, Provider, forwardRef, HostListener, ContentChild, EventEmitter} from 'angular2/core';
+import {NG_VALUE_ACCESSOR} from 'angular2/common';
import {RadioButton} from './radio-button';
import {ListHeader} from '../list/list';
import {isDefined} from '../../util/util';
+const RADIO_VALUE_ACCESSOR = new Provider(
+ NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => RadioGroup), multi: true});
/**
* @name RadioGroup
* @description
- * A radio group is a group of radio components, and its value comes
- * from the selected radio button's value. Selecting a radio button
- * in the group unselects all others in the group.
+ * A radio group is a group of radio button components, and its value
+ * comes from the checked radio button's value. Selecting a radio
+ * button in the group unchecks all others in the group.
*
- * See the [Angular 2 Docs](https://angular.io/docs/js/latest/api/forms/) for more info on forms and input.
+ * See the [Angular 2 Docs](https://angular.io/docs/ts/latest/guide/forms.html)
+ * for more info on forms and inputs.
*
* @usage
* ```html
@@ -30,7 +33,7 @@ import {isDefined} from '../../util/util';
*
*
* Duesenberg
- *
+ *
*
*
*
@@ -50,6 +53,7 @@ import {isDefined} from '../../util/util';
*
*
* ```
+ *
* @demo /docs/v2/demos/radio/
* @see {@link /docs/v2/components#radio Radio Component Docs}
*/
@@ -58,116 +62,137 @@ import {isDefined} from '../../util/util';
host: {
'[attr.aria-activedescendant]': 'activeId',
'role': 'radiogroup'
- }
+ },
+ providers: [RADIO_VALUE_ACCESSOR]
})
export class RadioGroup {
- private _buttons: Array = [];
+ private _btns: Array = [];
+ private _fn: Function;
private _ids: number = -1;
private _init: boolean = false;
/**
* @private
*/
- id;
+ value: any;
/**
* @private
*/
- value;
+ id: number;
/**
- * @private
+ * @output {any} expression to be evaluated when selection has been changed
*/
@Output() change: EventEmitter = new EventEmitter();
constructor(
- @Optional() ngControl: NgControl,
private _renderer: Renderer,
private _elementRef: ElementRef
) {
this.id = ++radioGroupIds;
-
- if (ngControl) {
- ngControl.valueAccessor = this;
- }
}
/**
* @private
- * Angular2 Forms API method called by the model (Control) on change to update
- * the checked value.
- * https://github.com/angular/angular/blob/master/modules/angular2/src/forms/directives/shared.ts#L34
*/
- writeValue(val) {
- if (val !== null) {
- let oldVal = this.value;
+ writeValue(val: any) {
+ console.debug('radio group, writeValue', val);
+ this.value = val;
- // set the radiogroup's value
- this.value = val || '';
-
- this.updateValue();
-
- // only emit change when it...changed
- if (this.value !== oldVal && this._init) {
- this.change.emit(this.value);
- }
-
- this._init = true;
+ if (this._init) {
+ this._update();
+ this.onTouched();
+ this.change.emit(val);
}
+
+ this._init = true;
}
/**
* @private
*/
ngAfterContentInit() {
- // in a setTimeout to prevent
- // Expression '_checked in RadioButton@0:24' has changed after
- // it was checked. Previous value: 'true'. Current value: 'false'
- // should be available in future versions of ng2
- setTimeout(() => {
- this.updateValue();
- });
- }
-
- /**
- * @private
- */
- private updateValue() {
- if (isDefined(this.value)) {
- // loop through each of the radiobuttons
- this._buttons.forEach(radioButton => {
-
- // check this radiobutton if its value is
- // the same as the radiogroups value
- let isChecked = (radioButton.value === this.value);
-
- radioButton.updateAsChecked(isChecked);
-
- if (isChecked) {
- // if this button is checked, then set it as
- // the radiogroup's active descendant
- this._renderer.setElementAttribute(this._elementRef.nativeElement, 'aria-activedescendant', radioButton.id);
- }
- });
+ let activeButton = this._btns.find(b => b.checked);
+ if (activeButton) {
+ this._setActive(activeButton);
}
}
/**
* @private
*/
- register(button: RadioButton): string {
- this._buttons.push(button);
+ registerOnChange(fn: Function): void {
+ this._fn = fn;
+ this.onChange = (val: any) => {
+ console.debug('radio group, onChange', val);
+ fn(val);
+ this.value = val;
+ this._update();
+ this.onTouched();
+ this.change.emit(val);
+ };
+ }
+
+ /**
+ * @private
+ */
+ registerOnTouched(fn) { this.onTouched = fn; }
+
+ /**
+ * @private
+ */
+ private _update() {
+ // loop through each of the radiobuttons
+ this._btns.forEach(radioButton => {
+
+ // check this radiobutton if its value is
+ // the same as the radiogroups value
+ radioButton.checked = (radioButton.value === this.value);
+
+ if (radioButton.checked) {
+ // if this button is checked, then set it as
+ // the radiogroup's active descendant
+ this._setActive(radioButton);
+ }
+ });
+ }
+
+ private _setActive(radioButton: RadioButton) {
+ this._renderer.setElementAttribute(this._elementRef.nativeElement, 'aria-activedescendant', radioButton.id);
+ }
+
+ /**
+ * @private
+ */
+ add(button: RadioButton): string {
+ this._btns.push(button);
// listen for radiobutton select events
- button.select.subscribe(() => {
+ button.select.subscribe((val) => {
// this radiobutton has been selected
- this.writeValue(button.value);
- this.onChange(button.value);
+ this.onChange(val);
});
return this.id + '-' + (++this._ids);
}
+ /**
+ * @private
+ */
+ remove(button: RadioButton) {
+ let index = this._btns.indexOf(button);
+ if (index > -1) {
+ if (button.value === this.value) {
+ this.value = null;
+ }
+ this._btns.splice(index, 1);
+ }
+ }
+
+ /**
+ * @private
+ */
@ContentChild(ListHeader)
private set _header(header) {
if (header) {
@@ -181,29 +206,12 @@ export class RadioGroup {
/**
* @private
*/
- onChange(val) {}
+ onChange(_) {}
/**
* @private
*/
- onTouched(val) {}
-
- /**
- * @private
- * Angular2 Forms API method called by the view (NgControl) to register the
- * onChange event handler that updates the model (Control).
- * https://github.com/angular/angular/blob/master/modules/angular2/src/forms/directives/shared.ts#L27
- * @param {Function} fn the onChange event handler.
- */
- registerOnChange(fn) { this.onChange = fn; }
-
- /**
- * @private
- * Angular2 Forms API method called by the the view (NgControl) to register
- * the onTouched event handler that marks the model (Control) as touched.
- * @param {Function} fn onTouched event handler.
- */
- registerOnTouched(fn) { this.onTouched = fn; }
+ onTouched() {}
}
diff --git a/ionic/components/radio/test/basic/index.ts b/ionic/components/radio/test/basic/index.ts
index 87116f9695..8cf419fe03 100644
--- a/ionic/components/radio/test/basic/index.ts
+++ b/ionic/components/radio/test/basic/index.ts
@@ -1,51 +1,53 @@
-import {App} from 'ionic/ionic';
-import {
- Control,
- ControlGroup,
- NgForm,
- Validators,
- NgControl,
- ControlValueAccessor,
- NgControlName,
- NgFormModel,
- FormBuilder
-} from 'angular2/common';
+import {App} from '../../../../../ionic/ionic';
+import {Control, ControlGroup} from 'angular2/common';
@App({
templateUrl: 'main.html'
})
class E2EApp {
+ fruits: Control;
+ fruitsForm: ControlGroup;
+ currenciesControl: Control;
+ currencyForm: ControlGroup;
+ currencies: Array;
+ items: Array<{description: string, value: any}>;
+ relationship: string;
+ pet: string;
+
constructor() {
- this.fruits = new Control("");
+ this.fruits = new Control('apple');
this.fruitsForm = new ControlGroup({
- "fruits": this.fruits
- });
-
- this.currenciesControl = new Control("");
-
- this.currencyForm = new ControlGroup({
- "currenciesControl": this.currenciesControl
+ 'fruits': this.fruits
});
this.currencies = ['USD', 'EUR'];
- this.selectedCurrency = 'EUR';
+ this.currenciesControl = new Control('EUR');
+ this.currencyForm = new ControlGroup({
+ 'currenciesControl': this.currenciesControl
+ });
this.relationship = 'enemies';
+ this.items = [
+ { description: 'value undefined', value: undefined },
+ { description: 'value false string', value: 'false' },
+ { description: 'value false boolean', value: false },
+ { description: 'value 0', value: 0 },
+ ];
}
setApple() {
- this.fruits.updateValue("apple");
+ this.fruits.updateValue('apple');
}
setBanana() {
- this.fruits.updateValue("banana");
+ this.fruits.updateValue('banana');
}
setCherry() {
- this.fruits.updateValue("cherry");
+ this.fruits.updateValue('cherry');
}
doSubmit(event) {
diff --git a/ionic/components/radio/test/basic/main.html b/ionic/components/radio/test/basic/main.html
index 5000028ecb..773b533563 100644
--- a/ionic/components/radio/test/basic/main.html
+++ b/ionic/components/radio/test/basic/main.html
@@ -16,7 +16,7 @@
Apple
-
+
@@ -56,7 +56,7 @@
{{currency}}
-
+
@@ -82,7 +82,7 @@
-
+
Dogs
@@ -99,4 +99,18 @@
pet: {{pet}}
+
+
+
+ {{ item.description }}
+
+
+
+
+
+
+
+ someNumber: {{someNumber}}
+
+
diff --git a/ionic/components/scroll/pull-to-refresh.ts b/ionic/components/scroll/pull-to-refresh.ts
index 4f16022de1..fdce69e5bf 100644
--- a/ionic/components/scroll/pull-to-refresh.ts
+++ b/ionic/components/scroll/pull-to-refresh.ts
@@ -18,9 +18,9 @@ import {raf, ready, CSS} from '../../util/dom';
* @usage
* ```html
*
- *
+ *
*
*
*
@@ -29,36 +29,28 @@ import {raf, ready, CSS} from '../../util/dom';
*
* ```ts
* export class MyClass {
- * constructor(){}
+ *
* doRefresh(refresher) {
- * console.debug('Refreshing!', refresher);
+ * console.log('Doing Refresh', refresher)
*
* setTimeout(() => {
- * console.debug('Pull to refresh complete!', refresher);
* refresher.complete();
- * })
+ * console.log("Complete");
+ * }, 5000);
* }
*
- * doStarting() {
- * console.debug('Pull started!');
+ * doStart(refresher) {
+ * console.log('Doing Start', refresher);
* }
*
- * doPulling(amt) {
- * console.debug('You have pulled', amt);
+ * doPulling(refresher) {
+ * console.log('Pulling', refresher);
* }
+ *
* }
* ```
* @demo /docs/v2/demos/refresher/
*
- * @property {string} [pullingIcon] - the icon you want to display when you begin to pull down
- * @property {string} [pullingText] - the text you want to display when you begin to pull down
- * @property {string} [refreshingIcon] - the icon you want to display when performing a refresh
- * @property {string} [refreshingText] - the text you want to display when performing a refresh
- *
- * @property {any} (refresh) - the methond on your class you want to perform when you refreshing
- * @property {any} (starting) - the methond on your class you want to perform when you start pulling down
- * @property {any} (pulling) - the methond on your class you want to perform when you are pulling down
- *
*/
@Component({
selector: 'ion-refresher',
@@ -174,22 +166,22 @@ export class Refresher {
/**
- * @private
+ * @input {string} the icon you want to display when you begin to pull down
*/
@Input() pullingIcon: string;
/**
- * @private
+ * @input {string} the text you want to display when you begin to pull down
*/
@Input() pullingText: string;
/**
- * @private
+ * @input {string} the icon you want to display when performing a refresh
*/
@Input() refreshingIcon: string;
/**
- * @private
+ * @input {string} the text you want to display when performing a refresh
*/
@Input() refreshingText: string;
@@ -200,19 +192,19 @@ export class Refresher {
/**
- * @private
+ * @output {event} When you are pulling down
*/
- @Output() pulling: EventEmitter = new EventEmitter();
+ @Output() pulling: EventEmitter = new EventEmitter();
/**
- * @private
+ * @output {event} When you are refreshing
*/
- @Output() refresh: EventEmitter = new EventEmitter();
+ @Output() refresh: EventEmitter = new EventEmitter();
/**
- * @private
+ * @output {event} When you start pulling down
*/
- @Output() starting: EventEmitter = new EventEmitter();
+ @Output() start: EventEmitter = new EventEmitter();
constructor(
@@ -313,7 +305,7 @@ export class Refresher {
activate() {
//this.ele.classList.add('active');
this.isActive = true;
- //this.starting.next();
+ this.start.emit(this);
}
/**
@@ -333,11 +325,10 @@ export class Refresher {
/**
* @private
*/
- start() {
+ startRefresh() {
// startCallback
this.isRefreshing = true;
- this.refresh.next(this);
- //$scope.$onRefresh();
+ this.refresh.emit(this);
}
/**
@@ -493,8 +484,8 @@ export class Refresher {
// overscroll according to the user's drag so far
this.overscroll( Math.round((this.deltaY - this.dragOffset) / 3) );
- // Pass an incremental pull amount to the EventEmitter
- this.pulling.next(this.lastOverscroll);
+ // Pass the refresher to the EventEmitter
+ this.pulling.emit(this);
// update the icon accordingly
if (!this.activated && this.lastOverscroll > this.ptrThreshold) {
@@ -531,7 +522,7 @@ export class Refresher {
// the user has scroll far enough to trigger a refresh
if (this.lastOverscroll > this.ptrThreshold) {
- this.start();
+ this.startRefresh();
this.scrollTo(this.ptrThreshold, this.scrollTime);
// the user has overscrolled but not far enough to trigger a refresh
diff --git a/ionic/components/scroll/scroll.ts b/ionic/components/scroll/scroll.ts
index 9f22e9b6c5..18d3867d2d 100644
--- a/ionic/components/scroll/scroll.ts
+++ b/ionic/components/scroll/scroll.ts
@@ -70,6 +70,7 @@ export class Scroll extends Ion {
}
/**
+ * @private
* Add a scroll event handler to the scroll element if it exists.
* @param {Function} handler The scroll handler to add to the scroll element.
* @returns {?Function} a function to remove the specified handler, otherwise
diff --git a/ionic/components/scroll/test/basic/index.ts b/ionic/components/scroll/test/basic/index.ts
index ff21e93aca..5a02c325b6 100644
--- a/ionic/components/scroll/test/basic/index.ts
+++ b/ionic/components/scroll/test/basic/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/scroll/test/pull-to-refresh/index.ts b/ionic/components/scroll/test/pull-to-refresh/index.ts
index f0958056d7..af2092418f 100644
--- a/ionic/components/scroll/test/pull-to-refresh/index.ts
+++ b/ionic/components/scroll/test/pull-to-refresh/index.ts
@@ -1,13 +1,27 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
templateUrl: 'main.html'
})
class E2EApp {
+ items = [];
+
+ constructor() {
+ for(let i = 0; i < 20; i++) {
+ this.items.push({ "index": i });
+ }
+ }
doRefresh(refresher) {
- console.log('DOREFRESH', refresher)
+ console.log('Doing Refresh', refresher)
+
+ // Add to the top of the list on refresh
+ let firstIndex = this.items[0].index - 1;
+
+ for(let i = firstIndex; i > firstIndex - 5; i--) {
+ this.items.unshift({ "index": i });
+ }
setTimeout(() => {
refresher.complete();
@@ -15,11 +29,11 @@ class E2EApp {
}, 5000);
}
- doStarting() {
- console.log('DOSTARTING');
+ doStart(refresher) {
+ console.log('Doing Start', refresher);
}
- doPulling(amt) {
- console.log('DOPULLING', amt);
+ doPulling(refresher) {
+ console.log('Pulling', refresher);
}
}
diff --git a/ionic/components/scroll/test/pull-to-refresh/main.html b/ionic/components/scroll/test/pull-to-refresh/main.html
index d3f8b974fb..f4029d0a4e 100644
--- a/ionic/components/scroll/test/pull-to-refresh/main.html
+++ b/ionic/components/scroll/test/pull-to-refresh/main.html
@@ -2,21 +2,17 @@
+ (start)="doStart($event)"
+ (refresh)="doRefresh($event)"
+ (pulling)="doPulling($event)"
+ pullingIcon="heart"
+ pullingText="release to refresh..."
+ refreshingIcon="star"
+ refreshingText="refreshing...">
-
-
-
-
-
-
-
+
+
+ Item {{ item.index }}
+
+
-
-
diff --git a/ionic/components/searchbar/searchbar.ts b/ionic/components/searchbar/searchbar.ts
index 7a218addd3..fd201d895b 100644
--- a/ionic/components/searchbar/searchbar.ts
+++ b/ionic/components/searchbar/searchbar.ts
@@ -42,19 +42,6 @@ export class SearchbarInput {
*
* ```
*
- * @property {string} [cancelButtonText=Cancel] - Sets the cancel button text to the value passed in
- * @property {boolean} [hideCancelButton=false] - Hides the cancel button
- * @property {string} [placeholder=Search] - Sets input placeholder to the value passed in
- *
- * @property {Any} [input] - Expression to evaluate when the Searchbar input has changed including cleared
- * @property {Any} [keydown] - Expression to evaluate when a key is pushed down in the Searchbar input
- * @property {Any} [keypress] - Expression to evaluate when a character is inserted in the Searchbar input
- * @property {Any} [keyup] - Expression to evaluate when a key is released in the Searchbar input
- * @property {Any} [blur] - Expression to evaluate when the Searchbar input has blurred
- * @property {Any} [focus] - Expression to evaluate when the Searchbar input has focused
- * @property {Any} [cancel] - Expression to evaluate when the cancel button is clicked
- * @property {Any} [clear] - Expression to evaluate when the clear input button is clicked
- *
* @demo /docs/v2/demos/searchbar/
* @see {@link /docs/v2/components#searchbar Searchbar Component Docs}
*/
@@ -79,40 +66,47 @@ export class Searchbar extends Ion {
@ViewChild(SearchbarInput) searchbarInput;
/**
- * @private
+ * @input {string} Sets the cancel button text to the value passed in
*/
@Input() cancelButtonText: string;
+
/**
- * @private
+ * @input {boolean} Hides the cancel button
*/
@Input() hideCancelButton: any;
+
/**
- * @private
+ * @input {string} Sets input placeholder to the value passed in
*/
@Input() placeholder: string;
+
/**
- * @private
+ * @input {any} Expression to evaluate when the Searchbar input has changed including cleared
*/
@Input() ngModel: any;
/**
- * @private
+ * @output {event} When the Searchbar input has changed including cleared
*/
@Output() input: EventEmitter = new EventEmitter();
+
/**
- * @private
+ * @output {event} When the Searchbar input has blurred
*/
@Output() blur: EventEmitter = new EventEmitter();
+
/**
- * @private
+ * @output {event} When the Searchbar input has focused
*/
@Output() focus: EventEmitter = new EventEmitter();
+
/**
- * @private
+ * @output {event} When the cancel button is clicked
*/
@Output() cancel: EventEmitter = new EventEmitter();
+
/**
- * @private
+ * @output {event} When the clear input button is clicked
*/
@Output() clear: EventEmitter = new EventEmitter();
diff --git a/ionic/components/searchbar/test/floating/index.ts b/ionic/components/searchbar/test/floating/index.ts
index 5713049de8..0844e09d10 100644
--- a/ionic/components/searchbar/test/floating/index.ts
+++ b/ionic/components/searchbar/test/floating/index.ts
@@ -1,6 +1,6 @@
import {FORM_DIRECTIVES, FormBuilder, Validators, Control, ControlGroup} from 'angular2/common';
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
templateUrl: 'main.html',
diff --git a/ionic/components/searchbar/test/nav/index.ts b/ionic/components/searchbar/test/nav/index.ts
index 44046163c4..10f1a73c9c 100644
--- a/ionic/components/searchbar/test/nav/index.ts
+++ b/ionic/components/searchbar/test/nav/index.ts
@@ -1,4 +1,4 @@
-import {App, Page, NavController} from 'ionic/ionic';
+import {App, Page, NavController} from '../../../../../ionic/ionic';
@Page({
templateUrl: 'first.html'
diff --git a/ionic/components/searchbar/test/toolbar/index.ts b/ionic/components/searchbar/test/toolbar/index.ts
index 810b63c5bc..119aac7c69 100644
--- a/ionic/components/searchbar/test/toolbar/index.ts
+++ b/ionic/components/searchbar/test/toolbar/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
templateUrl: 'main.html'
diff --git a/ionic/components/segment/segment.ios.scss b/ionic/components/segment/segment.ios.scss
index 9cdbfadf01..ba66f9d215 100644
--- a/ionic/components/segment/segment.ios.scss
+++ b/ionic/components/segment/segment.ios.scss
@@ -4,27 +4,34 @@
// iOS Segment
// --------------------------------------------------
-$segment-button-ios-bg-color: transparent !default;
-$segment-button-ios-bg-color-activated: $toolbar-ios-active-color !default;
+$segment-button-ios-bg-color: transparent !default;
+$segment-button-ios-bg-color-activated: $toolbar-ios-active-color !default;
-$segment-button-ios-text-color: inverse($segment-button-ios-bg-color-activated) !default;
-$segment-button-ios-activated-transition: 100ms all linear !default;
-$segment-button-ios-hover-transition: 100ms all linear !default;
-$segment-button-ios-active-transition: 100ms all linear !default;
-$segment-button-ios-hover-opacity: 0.1 !default;
-$segment-button-ios-active-opacity: 0.16 !default;
+$segment-button-ios-text-color: inverse($segment-button-ios-bg-color-activated) !default;
+$segment-button-ios-activated-transition: 100ms all linear !default;
+$segment-button-ios-hover-transition: 100ms all linear !default;
+$segment-button-ios-active-transition: 100ms all linear !default;
+$segment-button-ios-hover-opacity: 0.1 !default;
+$segment-button-ios-active-opacity: 0.16 !default;
-$segment-button-ios-border-width: 1px !default;
-$segment-button-ios-min-height: 3.0rem !default;
-$segment-button-ios-line-height: 3.0rem !default;
-$segment-button-ios-font-size: 1.3rem !default;
-$segment-button-ios-border-radius: 4px !default;
+$segment-button-ios-border-width: 1px !default;
+$segment-button-ios-height: 3.2rem !default;
+$segment-button-ios-line-height: 3.0rem !default;
+$segment-button-ios-font-size: 1.3rem !default;
+$segment-button-ios-border-radius: 4px !default;
+$segment-button-ios-icon-size: 2.6rem !default;
+$segment-button-ios-icon-line-height: 2.8rem !default;
-$segment-button-ios-toolbar-button-max-width: 100px !default;
+$segment-button-ios-toolbar-button-max-width: 100px !default;
+$segment-button-ios-toolbar-button-height: 2.6rem !default;
+$segment-button-ios-toolbar-line-height: 2.5rem !default;
+$segment-button-ios-toolbar-font-size: 1.2rem !default;
+$segment-button-ios-toolbar-icon-size: 2.2rem !default;
+$segment-button-ios-toolbar-icon-line-height: 2.4rem !default;
.segment-button {
- min-height: $segment-button-ios-min-height;
+ height: $segment-button-ios-height;
line-height: $segment-button-ios-line-height;
font-size: $segment-button-ios-font-size;
@@ -35,6 +42,11 @@ $segment-button-ios-toolbar-button-max-width: 100px !default;
color: $segment-button-ios-bg-color-activated;
background-color: $segment-button-ios-bg-color;
+ ion-icon {
+ font-size: $segment-button-ios-icon-size;
+ line-height: $segment-button-ios-icon-line-height;
+ }
+
&.segment-activated {
opacity: 1;
color: $segment-button-ios-text-color;
@@ -46,10 +58,10 @@ $segment-button-ios-toolbar-button-max-width: 100px !default;
background-color: rgba($segment-button-ios-bg-color-activated, $segment-button-ios-hover-opacity);
transition: $segment-button-ios-hover-transition;
}
-
+
&:active:not(.segment-activated) {
- background-color: rgba($segment-button-ios-bg-color-activated, $segment-button-ios-active-opacity);
- transition: $segment-button-ios-active-transition;
+ background-color: rgba($segment-button-ios-bg-color-activated, $segment-button-ios-active-opacity);
+ transition: $segment-button-ios-active-transition;
}
&:first-of-type {
@@ -80,9 +92,14 @@ $segment-button-ios-toolbar-button-max-width: 100px !default;
.segment-button {
max-width: $segment-button-ios-toolbar-button-max-width;
- min-height: 2.4rem;
- line-height: 2.4rem;
- font-size: 1.2rem;
+ height: $segment-button-ios-toolbar-button-height;
+ line-height: $segment-button-ios-toolbar-line-height;
+ font-size: $segment-button-ios-toolbar-font-size;
+
+ ion-icon {
+ font-size: $segment-button-ios-toolbar-icon-size;
+ line-height: $segment-button-ios-toolbar-icon-line-height;
+ }
}
}
@@ -100,7 +117,10 @@ $segment-button-ios-toolbar-button-max-width: 100px !default;
background-color: rgba($color-value, $segment-button-ios-hover-opacity);
}
- &.activated,
+ &:active:not(.segment-activated) {
+ background-color: rgba($color-value, $segment-button-ios-active-opacity);
+ }
+
&.segment-activated {
color: inverse($color-value);
background-color: $color-value;
@@ -119,4 +139,4 @@ $segment-button-ios-toolbar-button-max-width: 100px !default;
.toolbar[#{$color-name}] .segment-button.segment-activated {
color: $color-value;
}
-}
\ No newline at end of file
+}
diff --git a/ionic/components/segment/segment.md.scss b/ionic/components/segment/segment.md.scss
index fd66826a99..6a22ff0915 100644
--- a/ionic/components/segment/segment.md.scss
+++ b/ionic/components/segment/segment.md.scss
@@ -11,9 +11,11 @@ $segment-button-md-border-bottom-width: 2px !default;
$segment-button-md-border-bottom-color: rgba(#000000, 0.10) !default;
$segment-button-md-padding: 0 6px !default;
-$segment-button-md-min-height: 4.0rem !default;
+$segment-button-md-height: 4.2rem !default;
$segment-button-md-line-height: 4.0rem !default;
$segment-button-md-font-size: 1.2rem !default;
+$segment-button-md-icon-size: 2.6rem !default;
+$segment-button-md-icon-line-height: $segment-button-md-line-height !default;
.segment-button {
@@ -22,7 +24,7 @@ $segment-button-md-font-size: 1.2rem !default;
border-bottom-style: solid;
border-bottom-color: $segment-button-md-border-bottom-color;
- min-height: $segment-button-md-min-height;
+ height: $segment-button-md-height;
line-height: $segment-button-md-line-height;
font-size: $segment-button-md-font-size;
@@ -34,6 +36,11 @@ $segment-button-md-font-size: 1.2rem !default;
background-color: transparent;
transition: 100ms all linear;
+ ion-icon {
+ font-size: $segment-button-md-icon-size;
+ line-height: $segment-button-md-icon-line-height;
+ }
+
&.activated,
&.segment-activated {
border-color: $segment-button-md-border-color-activated;
diff --git a/ionic/components/segment/segment.ts b/ionic/components/segment/segment.ts
index 5c4c6f2d91..25ac9e8368 100644
--- a/ionic/components/segment/segment.ts
+++ b/ionic/components/segment/segment.ts
@@ -38,8 +38,6 @@ import {isDefined} from '../../util/util';
*
* ```
*
- * @property {string} [value] - the value of the segment button. Required.
- * @property {Any} (select) - expression to evaluate when a segment button has been clicked
*
* @demo /docs/v2/demos/segment/
* @see {@link /docs/v2/components#segment Segment Component Docs}
@@ -59,12 +57,12 @@ import {isDefined} from '../../util/util';
export class SegmentButton {
/**
- * @private
+ * @input {string} the value of the segment button. Required.
*/
@Input() value: string;
/**
- * @private
+ * @output {any} expression to evaluate when a segment button has been clicked
*/
@Output() select: EventEmitter = new EventEmitter();
@@ -138,7 +136,6 @@ export class SegmentButton {
*
* ```
*
- * @property {Any} (change) - expression to evaluate when a segment button has been changed
*
* @demo /docs/v2/demos/segment/
* @see {@link /docs/v2/components#segment Segment Component Docs}
@@ -156,7 +153,7 @@ export class Segment {
/**
- * @private
+ * @output {Any} expression to evaluate when a segment button has been changed
*/
@Output() change: EventEmitter = new EventEmitter();
diff --git a/ionic/components/segment/test/basic/index.ts b/ionic/components/segment/test/basic/index.ts
index 3b77594c40..7898550f4e 100644
--- a/ionic/components/segment/test/basic/index.ts
+++ b/ionic/components/segment/test/basic/index.ts
@@ -1,6 +1,6 @@
import {FORM_DIRECTIVES, FormBuilder, Validators, Control, ControlGroup} from 'angular2/common';
-import {App, IonicApp} from 'ionic/ionic';
+import {App, IonicApp} from '../../../../../ionic/ionic';
@App({
@@ -9,15 +9,17 @@ import {App, IonicApp} from 'ionic/ionic';
directives: [FORM_DIRECTIVES]
})
class MyApp {
- constructor(fb: FormBuilder, app: IonicApp) {
- this.app = app;
+ relationship: string = 'enemies';
+ modelStyle: string = 'B';
+ appType: string = 'free';
+ icons: string = 'camera';
+
+ myForm;
+
+ constructor(fb: FormBuilder) {
this.myForm = fb.group({
mapStyle: ['hybrid', Validators.required]
});
-
- this.relationship = 'enemies';
- this.modelStyle = 'B';
- this.appType = 'free';
}
onSegmentChanged(segmentButton) {
diff --git a/ionic/components/segment/test/basic/main.html b/ionic/components/segment/test/basic/main.html
index aee8242f50..bd439bb22e 100644
--- a/ionic/components/segment/test/basic/main.html
+++ b/ionic/components/segment/test/basic/main.html
@@ -15,12 +15,12 @@
-
-
- Something
+
+
+
-
- Else
+
+
@@ -80,6 +80,15 @@
Model Style: Model {{ modelStyle }}
+
+
+
+
+
+
+
+
+
diff --git a/ionic/components/segment/test/nav/index.ts b/ionic/components/segment/test/nav/index.ts
index 7bdae186f2..e8b40ba636 100644
--- a/ionic/components/segment/test/nav/index.ts
+++ b/ionic/components/segment/test/nav/index.ts
@@ -1,5 +1,5 @@
import {Validators, Control, ControlGroup} from 'angular2/common';
-import {App, Page, NavController} from 'ionic/ionic';
+import {App, Page, NavController} from '../../../../../ionic/ionic';
@Page({
diff --git a/ionic/components/segment/test/swipe/index.ts b/ionic/components/segment/test/swipe/index.ts
index 1ffab619b0..158b6ec662 100644
--- a/ionic/components/segment/test/swipe/index.ts
+++ b/ionic/components/segment/test/swipe/index.ts
@@ -1,7 +1,6 @@
import {Validators, Control, ControlGroup} from 'angular2/common';
import {Http} from 'angular2/http';
-import {App, Page, IonicApp, NavController} from 'ionic/ionic';
-import _ from 'lodash';
+import {App, Page, IonicApp, NavController} from '../../../../../ionic/ionic';
@Page({
diff --git a/ionic/components/select/select.ts b/ionic/components/select/select.ts
index d17e7e7887..41942a137c 100644
--- a/ionic/components/select/select.ts
+++ b/ionic/components/select/select.ts
@@ -1,5 +1,5 @@
-import {Component, Optional, ElementRef, Renderer, Input, Output, EventEmitter, HostListener, ContentChildren, QueryList} from 'angular2/core';
-import {NgControl} from 'angular2/common';
+import {Component, Optional, ElementRef, Renderer, Input, Output, Provider, forwardRef, EventEmitter, HostListener, ContentChildren, QueryList} from 'angular2/core';
+import {NG_VALUE_ACCESSOR} from 'angular2/common';
import {Alert} from '../alert/alert';
import {Form} from '../../util/form';
@@ -8,6 +8,10 @@ import {merge, isTrueProperty, isBlank} from '../../util/util';
import {NavController} from '../nav/nav-controller';
import {Option} from '../option/option';
+const SELECT_VALUE_ACCESSOR = new Provider(
+ NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => Select), multi: true});
+
+
/**
* @name Select
* @description
@@ -92,12 +96,6 @@ import {Option} from '../option/option';
* subTitle: 'Select your toppings'
* };
* ```
- * @property [cancelText] - The text of the cancel button. Defatuls to 'cancel'
- * @property [okText] - The text of the ok button. Defatuls to 'OK'
- * @property [alertOptions] - Any addition options that an alert can take. Title, Subtitle, etc.
- * @property [multiple] - Whether or not the select component can accept multipl selections
- * @property [disabled] - Whether or not the select component is disabled or not
- * @property (change) - Any expression you want to evaluate when the selection has changed
*
* @demo /docs/v2/demos/select/
*/
@@ -116,7 +114,8 @@ import {Option} from '../option/option';
'',
host: {
'[class.select-disabled]': '_disabled'
- }
+ },
+ providers: [SELECT_VALUE_ACCESSOR]
})
export class Select {
private _disabled: any = false;
@@ -126,6 +125,7 @@ export class Select {
private _values: Array = [];
private _texts: Array = [];
private _text: string = '';
+ private _fn: Function;
/**
* @private
@@ -134,16 +134,19 @@ export class Select {
/**
* @private
+ * @input {string} The text of the cancel button. Defatuls to `Cancel`
*/
@Input() cancelText: string = 'Cancel';
/**
* @private
+ * @input {string} The text of the ok button. Defatuls to `OK`
*/
@Input() okText: string = 'OK';
/**
* @private
+ * @input {any} Any addition options that an alert can take. Title, Subtitle, etc.
*/
@Input() alertOptions: any = {};
@@ -153,24 +156,24 @@ export class Select {
@Input() checked: any = false;
/**
- * @private
+ * @output {any} Any expression you want to evaluate when the selection has changed
*/
@Output() change: EventEmitter = new EventEmitter();
+ /**
+ * @output {any} Any expression you want to evaluate when the selection was cancelled
+ */
+ @Output() cancel: EventEmitter = new EventEmitter();
+
constructor(
private _form: Form,
private _elementRef: ElementRef,
private _renderer: Renderer,
@Optional() private _item: Item,
- @Optional() private _nav: NavController,
- @Optional() ngControl: NgControl
+ @Optional() private _nav: NavController
) {
this._form.register(this);
- if (ngControl) {
- ngControl.valueAccessor = this;
- }
-
if (_item) {
this.id = 'sel-' + _item.registerInput('select');
this._labelId = 'lbl-' + _item.id;
@@ -198,7 +201,12 @@ export class Select {
// make sure their buttons array is removed from the options
// and we create a new array for the alert's two buttons
- alertOptions.buttons = [this.cancelText];
+ alertOptions.buttons = [{
+ text: this.cancelText,
+ handler: () => {
+ this.cancel.emit(null);
+ }
+ }];
// if the alertOptions didn't provide an title then use the label's text
if (!alertOptions.title && this._item) {
@@ -231,7 +239,6 @@ export class Select {
alert.addButton({
text: this.okText,
handler: selectedValues => {
- this.value = selectedValues;
this.onChange(selectedValues);
this.change.emit(selectedValues);
}
@@ -242,33 +249,18 @@ export class Select {
/**
- * @private
+ * @input {boolean} Whether or not the select component can accept multipl selections
*/
@Input()
- get multiple() {
+ get multiple(): any {
return this._multi;
}
- set multiple(val) {
+ set multiple(val: any) {
this._multi = isTrueProperty(val);
}
- /**
- * @private
- */
- @Input()
- get value(): any {
- return (this._multi ? this._values : this._values.join());
- }
-
- set value(val: any) {
- // passed in value could be either an array, undefined or a string
- this._values = (Array.isArray(val) ? val : isBlank(val) ? [] : [val]);
- this.updateOptions();
- }
-
-
/**
* @private
*/
@@ -289,13 +281,13 @@ export class Select {
this._values = val.toArray().filter(o => o.checked).map(o => o.value);
}
- this.updateOptions();
+ this._updOpts();
}
/**
* @private
*/
- private updateOptions() {
+ private _updOpts() {
this._texts = [];
if (this._options) {
@@ -311,22 +303,8 @@ export class Select {
this._text = this._texts.join(', ');
}
-
/**
- * @private
- */
- ngAfterContentInit() {
- // using a setTimeout here to prevent
- // "has changed after it was checked" error
- // this will be fixed in future ng2 versions
- setTimeout(()=> {
- this.onChange(this._values);
- });
- }
-
-
- /**
- * @private
+ * @input {boolean} Whether or not the select component is disabled or not
*/
@Input()
get disabled() {
@@ -340,41 +318,49 @@ export class Select {
/**
* @private
- * Angular2 Forms API method called by the model (Control) on change to update
- * the checked value.
- * https://github.com/angular/angular/blob/master/modules/angular2/src/forms/directives/shared.ts#L34
*/
- writeValue(val) {
- this.value = val;
+ writeValue(val: any) {
+ console.debug('select, writeValue', val);
+ this._values = (Array.isArray(val) ? val : isBlank(val) ? [] : [val]);
+ this._updOpts();
}
/**
* @private
*/
- onChange(val) {}
+ ngAfterContentInit() {
+ this._updOpts();
+ }
/**
* @private
*/
- onTouched(val) {}
+ registerOnChange(fn: Function): void {
+ this._fn = fn;
+ this.onChange = (val: any) => {
+ console.debug('select, onChange', val);
+ fn(val);
+ this._values = (Array.isArray(val) ? val : isBlank(val) ? [] : [val]);
+ this._updOpts();
+ this.onTouched();
+ };
+ }
/**
* @private
- * Angular2 Forms API method called by the view (NgControl) to register the
- * onChange event handler that updates the model (Control).
- * https://github.com/angular/angular/blob/master/modules/angular2/src/forms/directives/shared.ts#L27
- * @param {Function} fn the onChange event handler.
- */
- registerOnChange(fn) { this.onChange = fn; }
-
- /**
- * @private
- * Angular2 Forms API method called by the the view (NgControl) to register
- * the onTouched event handler that marks model (Control) as touched.
- * @param {Function} fn onTouched event handler.
*/
registerOnTouched(fn) { this.onTouched = fn; }
+ /**
+ * @private
+ */
+ onChange(_) {}
+
+ /**
+ * @private
+ */
+ onTouched() {}
+
/**
* @private
*/
diff --git a/ionic/components/select/test/multiple-value/index.ts b/ionic/components/select/test/multiple-value/index.ts
index 70d2f5caae..ecedff89d8 100644
--- a/ionic/components/select/test/multiple-value/index.ts
+++ b/ionic/components/select/test/multiple-value/index.ts
@@ -1,16 +1,23 @@
-import {App, Page} from 'ionic/ionic';
+import {App, Page} from '../../../../../ionic/ionic';
@Page({
templateUrl: 'main.html'
})
class E2EPage {
+ toppings: Array;
+ carFeatures: Array;
+ pets: Array;
+ petOptions: Array<{text: string, value: string}>;
constructor() {
+ this.toppings = ['bacon', 'xcheese'];
+ this.carFeatures = [];
+ this.pets = ['cat', 'dog'];
this.petOptions = [
{ text: 'Bird', value: 'bird' },
- { text: 'Cat', value: 'cat', checked: true },
- { text: 'Dog', value: 'dog', checked: true },
+ { text: 'Cat', value: 'cat' },
+ { text: 'Dog', value: 'dog' },
{ text: 'Honey Badger', value: 'honeybadger' },
{ text: 'Pig', value: 'pig' },
];
@@ -27,6 +34,8 @@ class E2EPage {
template: ' '
})
class E2EApp {
+ root;
+
constructor() {
this.root = E2EPage;
}
diff --git a/ionic/components/select/test/multiple-value/main.html b/ionic/components/select/test/multiple-value/main.html
index f2ffdcf7df..7c0cbeb383 100644
--- a/ionic/components/select/test/multiple-value/main.html
+++ b/ionic/components/select/test/multiple-value/main.html
@@ -7,9 +7,9 @@
Toppings
- Bacon
+ Bacon
Black Olives
- Extra Cheese
+ Extra Cheese
Green Peppers
Mushrooms
Onions
@@ -35,7 +35,7 @@
Pets
- {{o.text}}
+ {{o.text}}
diff --git a/ionic/components/select/test/single-value/index.ts b/ionic/components/select/test/single-value/index.ts
index 3459f210f1..0c1bd8365b 100644
--- a/ionic/components/select/test/single-value/index.ts
+++ b/ionic/components/select/test/single-value/index.ts
@@ -1,11 +1,25 @@
-import {App, Page} from 'ionic/ionic';
+import {App, Page} from '../../../../../ionic/ionic';
@Page({
templateUrl: 'main.html'
})
class E2EPage {
+ musicAlertOpts;
+ gender: string;
+ gaming: string;
+ os: string;
+ music: string;
+ month: string;
+ year: string;
+
constructor() {
+ this.gaming = '';
+ this.os = 'win3.1';
+ this.music = null;
+ this.month = '12';
+ this.year = '1994';
+
this.musicAlertOpts = {
title: '1994 Music',
subTitle: 'Select your favorite'
@@ -16,6 +30,14 @@ class E2EPage {
}, 1500);
}
+ gamingCancel() {
+ console.log('Gaming Select, Cancel');
+ }
+
+ gamingChange(selectedValue) {
+ console.log('Gaming Select, Change value:', selectedValue);
+ }
+
stpSelect() {
console.log('STP selected')
}
@@ -30,6 +52,8 @@ class E2EPage {
template: ' '
})
class E2EApp {
+ root;
+
constructor() {
this.root = E2EPage;
}
diff --git a/ionic/components/select/test/single-value/main.html b/ionic/components/select/test/single-value/main.html
index 404849ea92..2082716d49 100644
--- a/ionic/components/select/test/single-value/main.html
+++ b/ionic/components/select/test/single-value/main.html
@@ -14,7 +14,7 @@
Gaming
-
+
NES
Nintendo64
PlayStation
@@ -31,7 +31,7 @@
Linux
Mac OS 7
Mac OS 8
- Windows 3.1
+ Windows 3.1
Windows 95
Windows 98
@@ -64,7 +64,7 @@
September
October
November
- December
+ December
1989
@@ -72,7 +72,7 @@
1991
1992
1993
- 1994
+ 1994
1995
1996
1997
diff --git a/ionic/components/show-hide-when/test/basic/index.ts b/ionic/components/show-hide-when/test/basic/index.ts
index 611ee2dc2a..43da3f5c87 100644
--- a/ionic/components/show-hide-when/test/basic/index.ts
+++ b/ionic/components/show-hide-when/test/basic/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
import {
Control,
ControlGroup,
diff --git a/ionic/components/slides/slides.ts b/ionic/components/slides/slides.ts
index c2b6c6090e..6f8da7db09 100644
--- a/ionic/components/slides/slides.ts
+++ b/ionic/components/slides/slides.ts
@@ -48,17 +48,6 @@ import {Scroll} from '../scroll/scroll';
*})
*
*```
- * @property {Boolean} [autoplay] - whether or not the slides should automatically change
- * @property {Boolean} [loop] - whether the slides should loop from the last slide back to the first
- * @property {Number} [index] - The slide index to start on
- * @property {Boolean} [bounce] - whether the slides should bounce
- * @property {Boolean} [pager] - Whether the slide should show the page or not
- * @property {Any} [options] - Any additional slider options you want to pass
- * @property {Number} [zoom] - Whether or not the slider can zoom in or out
- * @property {Number} [zoomDuration] - how long it should take to zoom a slide
- * @property {Number} [zoomMax] - the max scale an slide can be zoomed
- * @property {Any} (change) - expression to evaluate when a slide has been changed
- * @property {Any} (move) - expression to evaluate when a slide is moving
* @demo /docs/v2/demos/slides/
* @see {@link /docs/v2/components#slides Slides Component Docs}
*
@@ -166,57 +155,62 @@ export class Slides extends Ion {
/**
- * @private
+ * @input {boolean} whether or not the slides should automatically change
*/
@Input() autoplay: any;
/**
- * @private
+ * @input {boolean} whether or not the slides should automatically change
*/
@Input() loop: any;
/**
- * @private
+ * @input {number} The slide index to start on
*/
@Input() index: any;
/**
- * @private
+ * @input {boolean} whether the slides should bounce
*/
@Input() bounce: any;
/**
- * @private
+ * @input {boolean} Whether the slide should show the page or not
*/
@Input() pager: any;
/**
- * @private
+ * @input {any} Any additional slider options you want to pass
*/
@Input() options: any;
/**
- * @private
+ * @input {number} Whether or not the slider can zoom in or out
*/
@Input() zoom: any;
/**
- * @private
+ * @input {number} how long it should take to zoom a slide
*/
@Input() zoomDuration: any;
/**
- * @private
+ * @input {number} the max scale an slide can be zoomed
*/
@Input() zoomMax: any;
/**
- * @private
+ * @output {any} expression to evaluate when a slide has been changed
*/
@Output() change: EventEmitter = new EventEmitter();
/**
- * @private
+ * @output {any} expression to evaluate when a slide change starts
+ */
+ @Output() slideChangeStart: EventEmitter = new EventEmitter();
+
+ /**
+ * @output {any} expression to evaluate when a slide moves
*/
@Output() move: EventEmitter = new EventEmitter();
@@ -276,6 +270,7 @@ export class Slides extends Ion {
return this.options.onTransitionEnd && this.options.onTransitionEnd(swiper, e);
};
options.onSlideChangeStart = (swiper) => {
+ this.slideChangeStart.emit(swiper);
return this.options.onSlideChangeStart && this.options.onSlideChangeStart(swiper);
};
options.onSlideChangeEnd = (swiper) => {
@@ -464,8 +459,7 @@ export class Slides extends Ion {
let zi = new Animation(this.touch.target.children[0])
.duration(this.zoomDuration)
- .easing('linear')
- .fill('none');
+ .easing('linear');
let zw = new Animation(this.touch.target.children[0])
.duration(this.zoomDuration)
diff --git a/ionic/components/slides/test/basic/index.ts b/ionic/components/slides/test/basic/index.ts
index cb020b52ff..981f2428a2 100644
--- a/ionic/components/slides/test/basic/index.ts
+++ b/ionic/components/slides/test/basic/index.ts
@@ -1,4 +1,4 @@
-import {App, IonicApp} from 'ionic/ionic';
+import {App, IonicApp} from '../../../../../ionic/ionic';
import {Http} from 'angular2/http';
@App({
@@ -22,14 +22,13 @@ class MyApp {
this.http.get(baseUrl + '?method=flickr.groups.pools.getPhotos&group_id=1463451@N25&safe_search=1&api_key='
+ FLICKR_API_KEY + '&nojsoncallback=1&format=json&tags=' + tags)
- .map(res => res.json())
.subscribe(data => {
- this.images = data.photos.photo.slice(0, 20);
+ this.images = data.json().photos.photo.slice(0, 20);
setTimeout(() => {
this.slider.update();
});
}, (err) => {
- alert('Unable to load images');
+ console.info('Unable to load images');
console.error(err);
})
}
diff --git a/ionic/components/slides/test/intro/index.ts b/ionic/components/slides/test/intro/index.ts
index f3795a8ce5..9f7ca60173 100644
--- a/ionic/components/slides/test/intro/index.ts
+++ b/ionic/components/slides/test/intro/index.ts
@@ -1,11 +1,51 @@
-import {App} from 'ionic/ionic';
+import {App, Page, NavController} from 'ionic/ionic';
@App({
- templateUrl: 'main.html'
+ template: ' '
})
class MyApp {
- onSlideChanged(slider) {
- console.log('Slide changed', slider);
+ constructor() {
+ this.rootPage = IntroPage;
}
}
+
+@Page({
+ templateUrl: 'main.html'
+})
+class IntroPage {
+ continueText: string = "Skip";
+
+ constructor(public nav: NavController) {
+
+ }
+
+ onSlideChanged(slider) {
+ console.log("Slide changed", slider);
+ }
+
+ onSlideChangeStart(slider) {
+ console.log("Slide change start", slider);
+ slider.isEnd ? this.continueText = "Continue" : this.continueText = "Skip";
+ }
+
+ skip() {
+ this.nav.push(MainPage);
+ }
+}
+
+@Page({
+ template: `
+
+ Slides
+
+
+
+ Another Page
+
+
+ `
+})
+class MainPage {
+
+}
diff --git a/ionic/components/slides/test/intro/main.html b/ionic/components/slides/test/intro/main.html
index dd0363c796..e46a13e618 100644
--- a/ionic/components/slides/test/intro/main.html
+++ b/ionic/components/slides/test/intro/main.html
@@ -1,3 +1,41 @@
+
+
+
+ {{continueText}}
+
+
+ Slides
+
+
+
+
+
+ Thank you for choosing the Awesome App!
+
+
+
+
+ The number one app for everything awesome.
+
+
+
+ Using Awesome
+
+
+
Just three steps:
+
+ Be awesome
+ Stay awesome
+ There is no step 3
+
+
+
+
+ Any questions?
+
+
+
+
-
-
-
- Skip
-
-
-
-
- Next
-
-
- Grid Icons
-
-
-
- Thank you for choosing the Awesome App!
-
-
-
-
- The number one app for everything awesome.
-
-
-
- Using Awesome
-
-
-
Just three steps:
-
- Be awesome
- Stay awesome
- There is no step 3
-
-
-
-
- Any questions?
-
-
diff --git a/ionic/components/slides/test/loop/index.ts b/ionic/components/slides/test/loop/index.ts
index ecee3ee043..e6d3d71cc3 100644
--- a/ionic/components/slides/test/loop/index.ts
+++ b/ionic/components/slides/test/loop/index.ts
@@ -1,4 +1,4 @@
-import {App, IonicApp} from 'ionic/ionic';
+import {App, IonicApp} from '../../../../../ionic/ionic';
@App({
templateUrl: 'main.html'
diff --git a/ionic/components/slides/test/scroll/index.ts b/ionic/components/slides/test/scroll/index.ts
index edfdcec9b6..1f71954369 100644
--- a/ionic/components/slides/test/scroll/index.ts
+++ b/ionic/components/slides/test/scroll/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
templateUrl: 'main.html',
diff --git a/ionic/components/tabs/tab.ts b/ionic/components/tabs/tab.ts
index fda936de71..30a96dd1d1 100644
--- a/ionic/components/tabs/tab.ts
+++ b/ionic/components/tabs/tab.ts
@@ -4,7 +4,7 @@ import {EventEmitter, Input, Output} from 'angular2/core';
import {IonicApp} from '../app/app';
import {Config} from '../../config/config';
import {Keyboard} from '../../util/keyboard';
-import {NavController} from '../nav/nav-controller';
+import {NavController, NavOptions} from '../nav/nav-controller';
import {ViewController} from '../nav/view-controller';
import {Tabs} from './tabs';
import {TabButton} from './tab-button';
@@ -69,14 +69,8 @@ import {TabButton} from './tab-button';
* ```
*
*
- * @property {Page} [root] - set the root page for this tab
- * @property {String} [tabTitle] - set the title of this tab
- * @property {String} [tabIcon] - set the icon for this tab
- * @property {Any} [tabBadge] - set the badge for this tab
- * @property {String} [tabBadgeStyle] - set the badge color for this tab
- * @property {Any} (select) - method to call when the current tab is selected
*
- * @demo /docs/v2/demos/tabs/
+ * @demo /docs/v2/demos/tabs/
*/
@Component({
selector: 'ion-tab',
@@ -105,36 +99,40 @@ export class Tab extends NavController {
*/
btn: TabButton;
-
/**
- * @private
+ * @input {Page} Set the root page for this tab
*/
@Input() root: Type;
/**
- * @private
+ * @input {object} Any nav-params you want to pass to the root page of the tab
+ */
+ @Input() rootParams: any;
+
+ /**
+ * @input {string} Set the title of this tab
*/
@Input() tabTitle: string;
/**
- * @private
+ * @input {string} Set the icon for this tab
*/
@Input() tabIcon: string;
/**
- * @private
+ * @input {string} Set the badge for this tab
*/
@Input() tabBadge: string;
/**
- * @private
+ * @input {string} Set the badge color for this tab
*/
@Input() tabBadgeStyle: string;
/**
- * @private
+ * @output {Tab} Method to call when the current tab is selected
*/
- @Output() select: EventEmitter = new EventEmitter();
+ @Output() select: EventEmitter = new EventEmitter();
constructor(
@Inject(forwardRef(() => Tabs)) parentTabs: Tabs,
@@ -166,9 +164,9 @@ export class Tab extends NavController {
/**
* @private
*/
- load(opts, done?: Function) {
+ load(opts: NavOptions, done?: Function) {
if (!this._loaded && this.root) {
- this.push(this.root, null, opts).then(() => {
+ this.push(this.root, this.rootParams, opts).then(() => {
done();
});
this._loaded = true;
@@ -182,7 +180,7 @@ export class Tab extends NavController {
/**
* @private
*/
- preload(wait) {
+ preload(wait: number) {
this._loadTimer = setTimeout(() => {
if (!this._loaded) {
console.debug('Tabs, preload', this.id);
@@ -201,7 +199,7 @@ export class Tab extends NavController {
/**
* @private
*/
- loadPage(viewCtrl, navbarContainerRef, opts, done) {
+ loadPage(viewCtrl: ViewController, navbarContainerRef: any, opts: NavOptions, done: Function) {
// by default a page's navbar goes into the shared tab's navbar section
navbarContainerRef = this.parent.navbarContainerRef;
@@ -223,7 +221,7 @@ export class Tab extends NavController {
/**
* @private
*/
- setSelected(isSelected) {
+ setSelected(isSelected: boolean) {
this.isSelected = isSelected;
this.hideNavbars(!isSelected);
}
@@ -231,7 +229,7 @@ export class Tab extends NavController {
/**
* @private
*/
- hideNavbars(shouldHideNavbars) {
+ hideNavbars(shouldHideNavbars: boolean) {
this._views.forEach(viewCtrl => {
let navbar = viewCtrl.getNavbar();
navbar && navbar.setHidden(shouldHideNavbars);
@@ -241,7 +239,7 @@ export class Tab extends NavController {
/**
* @private
*/
- get index() {
+ get index(): number {
return this.parent.getIndex(this);
}
diff --git a/ionic/components/tabs/tabs.ts b/ionic/components/tabs/tabs.ts
index 645744a5e3..ae315ca945 100644
--- a/ionic/components/tabs/tabs.ts
+++ b/ionic/components/tabs/tabs.ts
@@ -1,4 +1,4 @@
-import {Component, Directive, ElementRef, Optional, Host, forwardRef, ViewContainerRef, ViewChild, ViewChildren, EventEmitter, Output, Input, Renderer} from 'angular2/core';
+import {Component, Directive, ElementRef, Optional, Host, forwardRef, ViewContainerRef, ViewChild, ViewChildren, EventEmitter, Output, Input, Renderer, Type} from 'angular2/core';
import {NgFor, NgIf} from 'angular2/common';
import {IonicApp} from '../app/app';
@@ -17,17 +17,6 @@ import {isUndefined, isTrueProperty} from '../../util/util';
/**
* @name Tabs
- * @property {any} [selectedIndex] - The default selected tab index when first loaded. If a selected index wasn't provided then it'll use `0`, the first tab.
- * @property {any} [tabbarPlacement] - set position of the tabbar, top or bottom
- * @property {any} [tabbarIcons] - set the position of the tabbar's icons: top, bottom, left, right, hide
- * @property {any} [preloadTabs] - sets whether to preload all the tabs, true or false
- * @property {any} (change) - expression you want to evaluate when the tabs chage
- * @usage
-* ```html
- *
- *
- *
- * ```
* @description
* _For basic Tabs usage, see the [Tabs section](../../../../components/#tabs)
* of the Component docs._
@@ -36,9 +25,18 @@ import {isUndefined, isTrueProperty} from '../../util/util';
* individual Tab components. On iOS, the TabBar is placed on the bottom of
* the screen, while on Android it is at the top.
*
+ * @usage
+ * ```html
+ *
+ *
+ *
+ * ```
+ *
* @demo /docs/v2/demos/tabs/
+ *
* @see {@link /docs/v2/components#tabs Tabs Component Docs}
* @see {@link ../Tab Tab API Docs}
+ *
*/
@Component({
selector: 'ion-tabs',
@@ -92,23 +90,27 @@ export class Tabs extends Ion {
subPages: boolean;
/**
- * @private
+ * @input {number} The default selected tab index when first loaded. If a selected index wasn't provided then it'll use `0`, the first tab.
*/
@Input() selectedIndex: any;
+
/**
- * @private
+ * @input {boolean} Sets whether to preload all the tabs, true or false
*/
@Input() preloadTabs: any;
+
/**
- * @private
+ * @input {string} set the position of the tabbar's icons: top, bottom, left, right, hide
*/
@Input() tabbarIcons: string;
+
/**
- * @private
+ * @input {string} Set position of the tabbar, top or bottom
*/
@Input() tabbarPlacement: string;
+
/**
- * @private
+ * @input {any} expression you want to evaluate when the tabs change
*/
@Output() change: EventEmitter = new EventEmitter();
@@ -116,14 +118,20 @@ export class Tabs extends Ion {
* @private
*/
@ViewChild(TabHighlight) private _highlight: TabHighlight;
+
/**
* @private
*/
@ViewChildren(TabButton) private _btns;
+ /**
+ * @private
+ */
+ parent: any
+
constructor(
@Optional() viewCtrl: ViewController,
- @Optional() public parent: NavController,
+ @Optional() parent: NavController,
private _app: IonicApp,
private _config: Config,
private _elementRef: ElementRef,
@@ -131,7 +139,7 @@ export class Tabs extends Ion {
private _renderer: Renderer
) {
super(_elementRef);
-
+ this.parent = parent;
this.id = ++tabIds;
this.subPages = _config.getBoolean('tabSubPages');
this._useHighlight = _config.getBoolean('tabbarHighlight');
@@ -169,6 +177,9 @@ export class Tabs extends Ion {
});
}
+ /**
+ * @private
+ */
ngAfterContentInit() {
let selectedIndex = this.selectedIndex ? parseInt(this.selectedIndex, 10) : 0;
@@ -266,9 +277,9 @@ export class Tabs extends Ion {
/**
* @param {number} index Index of the tab you want to get
- * @returns {Any} Tab Returs the tab who's index matches the one passed
+ * @returns {Tab} Returns the tab who's index matches the one passed
*/
- getByIndex(index: number): any {
+ getByIndex(index: number): Tab {
if (index < this._tabs.length && index > -1) {
return this._tabs[index];
}
@@ -276,7 +287,7 @@ export class Tabs extends Ion {
}
/**
- * @return {Any} Tab Returns the currently selected tab
+ * @return {Tab} Returns the currently selected tab
*/
getSelected(): Tab {
for (let i = 0; i < this._tabs.length; i++) {
@@ -299,7 +310,7 @@ export class Tabs extends Ion {
* "Touch" the active tab, going back to the root view of the tab
* or optionally letting the tab handle the event
*/
- private _touchActive(tab) {
+ private _touchActive(tab: Tab) {
let active = tab.getActive();
if (!active) {
@@ -335,7 +346,7 @@ export class Tabs extends Ion {
* within a NavController.
* @returns {NavController}
*/
- get rootNav() {
+ get rootNav(): NavController {
let nav = this.parent;
while (nav.parent) {
nav = nav.parent;
diff --git a/ionic/components/tabs/test/advanced/index.ts b/ionic/components/tabs/test/advanced/index.ts
index f8786ce6fd..85361cc40c 100644
--- a/ionic/components/tabs/test/advanced/index.ts
+++ b/ionic/components/tabs/test/advanced/index.ts
@@ -1,7 +1,7 @@
import {ViewChild} from 'angular2/core';
import {RouteConfig, Location} from 'angular2/router';
-import {App, Page, NavController, Modal, ViewController, Tabs} from 'ionic/ionic';
+import {App, Page, NavController, NavParams, Modal, ViewController, Tabs} from '../../../../../ionic/ionic';
@Page({
@@ -27,12 +27,12 @@ import {App, Page, NavController, Modal, ViewController, Tabs} from 'ionic/ionic
`
})
class SignIn {
- constructor(nav: NavController) {
- this.nav = nav;
- }
+ constructor(private nav: NavController) {}
push() {
- this.nav.push(TabsPage);
+ this.nav.push(TabsPage, {
+ userId: 8675309
+ });
}
}
@@ -48,9 +48,7 @@ class SignIn {
`
})
class ChatPage {
- constructor(viewCtrl: ViewController) {
- this.viewCtrl = viewCtrl;
- }
+ constructor(private viewCtrl: ViewController) {}
}
@@ -60,8 +58,9 @@ class ChatPage {
class TabsPage {
@ViewChild(Tabs) tabs: Tabs;
- constructor(private nav: NavController) {
+ constructor(private nav: NavController, private params: NavParams) {
this.tab1Root = Tab1Page1;
+ this.tab1Params = params;
this.tab2Root = Tab2Page1;
this.tab3Root = Tab3Page1;
}
@@ -98,14 +97,16 @@ class TabsPage {
'Go to Tab 1, Page 2
' +
'Logout
' +
'Favorites Tab
' +
+ 'UserId: {{userId}}
' +
' ' +
' ' +
' '
})
class Tab1Page1 {
- constructor(nav: NavController, tabs: Tabs) {
- this.nav = nav;
- this.tabs = tabs;
+ userId: string;
+
+ constructor(private nav: NavController, private tabs: Tabs, private params: NavParams) {
+ this.userId = params.get('userId');
}
push() {
@@ -135,9 +136,7 @@ class Tab1Page1 {
''
})
class Tab1Page2 {
- constructor(nav: NavController) {
- this.nav = nav;
- }
+ constructor(private nav: NavController) {}
push() {
this.nav.push(Tab1Page3)
@@ -157,9 +156,7 @@ class Tab1Page2 {
''
})
class Tab1Page3 {
- constructor(nav: NavController) {
- this.nav = nav;
- }
+ constructor(private nav: NavController) {}
}
@@ -179,9 +176,7 @@ class Tab1Page3 {
''
})
class Tab2Page1 {
- constructor(nav: NavController) {
- this.nav = nav;
- }
+ constructor(private nav: NavController) {}
push() {
this.nav.push(Tab2Page2)
@@ -202,9 +197,7 @@ class Tab2Page1 {
''
})
class Tab2Page2 {
- constructor(nav: NavController) {
- this.nav = nav;
- }
+ constructor(private nav: NavController) {}
push() {
this.nav.push(Tab2Page3)
@@ -224,9 +217,7 @@ class Tab2Page2 {
''
})
class Tab2Page3 {
- constructor(nav: NavController) {
- this.nav = nav;
- }
+ constructor(private nav: NavController) {}
}
diff --git a/ionic/components/tabs/test/advanced/tabs.html b/ionic/components/tabs/test/advanced/tabs.html
index 77f729032e..d104d78062 100644
--- a/ionic/components/tabs/test/advanced/tabs.html
+++ b/ionic/components/tabs/test/advanced/tabs.html
@@ -1,6 +1,6 @@
-
+
diff --git a/ionic/components/tabs/test/badges/index.ts b/ionic/components/tabs/test/badges/index.ts
index cdb0c6642f..afc358b1fa 100644
--- a/ionic/components/tabs/test/badges/index.ts
+++ b/ionic/components/tabs/test/badges/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
@App({
diff --git a/ionic/components/tabs/test/basic/index.ts b/ionic/components/tabs/test/basic/index.ts
index bd293e6257..b859cb557b 100644
--- a/ionic/components/tabs/test/basic/index.ts
+++ b/ionic/components/tabs/test/basic/index.ts
@@ -1,4 +1,4 @@
- import {App, Page, NavController, Alert, Modal, ViewController} from 'ionic/ionic';
+ import {App, Page, NavController, Alert, Modal, ViewController} from '../../../../../ionic/ionic';
//
// Modal
@@ -23,9 +23,10 @@
Tracks
-
- Toggle {{i}}
-
+
+ Toggle {{i}}
+
+
diff --git a/ionic/components/tabs/test/ghost/index.ts b/ionic/components/tabs/test/ghost/index.ts
index dabcba3148..1de90c7070 100644
--- a/ionic/components/tabs/test/ghost/index.ts
+++ b/ionic/components/tabs/test/ghost/index.ts
@@ -1,4 +1,4 @@
- import {App, Page, NavController, Tab} from 'ionic/ionic';
+ import {App, Page, NavController, Tab} from '../../../../../ionic/ionic';
import {ContentChild, QueryList, ViewChildren} from 'angular2/core';
diff --git a/ionic/components/tabs/test/tab-bar-scenarios/index.ts b/ionic/components/tabs/test/tab-bar-scenarios/index.ts
index 45d9e0103e..67b9bf20ba 100644
--- a/ionic/components/tabs/test/tab-bar-scenarios/index.ts
+++ b/ionic/components/tabs/test/tab-bar-scenarios/index.ts
@@ -1,4 +1,4 @@
-import {App, Page} from 'ionic/ionic';
+import {App, Page} from '../../../../../ionic/ionic';
@Page({template:'hi'})
diff --git a/ionic/components/tap-click/test/tapClick.spec.ts b/ionic/components/tap-click/test/tapClick.spec.ts
index b275d3d6d6..58f7d64ac7 100644
--- a/ionic/components/tap-click/test/tapClick.spec.ts
+++ b/ionic/components/tap-click/test/tapClick.spec.ts
@@ -1,4 +1,4 @@
-import * as tapClick from 'ionic/ionic';
+import * as tapClick from '../../../../ionic/ionic';
export function run() {
diff --git a/ionic/components/toggle/test/basic/e2e.ts b/ionic/components/toggle/test/basic/e2e.ts
index 019e051d17..b114c16c5b 100644
--- a/ionic/components/toggle/test/basic/e2e.ts
+++ b/ionic/components/toggle/test/basic/e2e.ts
@@ -1,6 +1,6 @@
it('should check apple via switch element click', function() {
- element(by.css('[value="apple"] button')).click();
+ element(by.css('[ngControl="appleCtrl"]')).click();
});
diff --git a/ionic/components/toggle/test/basic/index.ts b/ionic/components/toggle/test/basic/index.ts
index 1d8c6a59c3..14930b585e 100644
--- a/ionic/components/toggle/test/basic/index.ts
+++ b/ionic/components/toggle/test/basic/index.ts
@@ -1,4 +1,4 @@
-import {App} from 'ionic/ionic';
+import {App} from '../../../../../ionic/ionic';
import {
Control,
ControlGroup,
@@ -15,18 +15,26 @@ import {
templateUrl: 'main.html'
})
class E2EApp {
+ fruitsForm: ControlGroup;
+ grapeDisabled: boolean;
+ grapeChecked: boolean;
+ kiwiModel: boolean;
+ strawberryModel: boolean;
+ formResults: string;
+
constructor() {
this.fruitsForm = new ControlGroup({
- "appleCtrl": new Control(),
+ "appleCtrl": new Control(false),
"bananaCtrl": new Control(true),
"cherryCtrl": new Control(false),
"grapeCtrl": new Control(true)
});
- this.grapeDisabled = true;
this.grapeChecked = true;
+ this.grapeDisabled = true;
- this.myModel = true;
+ this.kiwiModel = true;
+ this.strawberryModel = false;
}
toggleGrapeChecked() {
diff --git a/ionic/components/toggle/test/basic/main.html b/ionic/components/toggle/test/basic/main.html
index e5089207c1..5d537a89a2 100644
--- a/ionic/components/toggle/test/basic/main.html
+++ b/ionic/components/toggle/test/basic/main.html
@@ -1,7 +1,6 @@
Toggles
-
{{formResults}}
diff --git a/ionic/components/toggle/toggle.ts b/ionic/components/toggle/toggle.ts
index 2a0554e10b..351cf33098 100644
--- a/ionic/components/toggle/toggle.ts
+++ b/ionic/components/toggle/toggle.ts
@@ -1,13 +1,16 @@
-import {Component, ElementRef, Renderer, Input, Optional} from 'angular2/core';
-import {NgControl} from 'angular2/common';
+import {Component, ElementRef, Renderer, Input, Optional, Provider, forwardRef} from 'angular2/core';
+import {ControlValueAccessor, NG_VALUE_ACCESSOR} from 'angular2/common';
import {Form} from '../../util/form';
-import {Config} from '../../config/config';
import {isTrueProperty} from '../../util/util';
import {Item} from '../item/item';
import {pointerCoord} from '../../util/dom';
+const TOGGLE_VALUE_ACCESSOR = new Provider(
+ NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => Toggle), multi: true});
+
+
/**
* @name Toggle
* @description
@@ -16,11 +19,11 @@ import {pointerCoord} from '../../util/dom';
* Toggles can also have colors assigned to them, by adding any color
* attribute.
*
- * See the [Angular 2 Docs](https://angular.io/docs/js/latest/api/forms/) for more info on forms and input.
- * @property {any} [value] - the inital value of the toggle
+ * See the [Angular 2 Docs](https://angular.io/docs/ts/latest/guide/forms.html)
+ * for more info on forms and inputs.
* @property {boolean} [checked] - whether the toggle it toggled or not
* @property {boolean} [disabled] - whether the toggle is disabled or not
- * @property {string} [id] - a unique ID for a toggle
+ *
* @usage
* ```html
*
@@ -28,26 +31,27 @@ import {pointerCoord} from '../../util/dom';
*
*
* Pepperoni
- *
+ *
*
*
*
* Sausage
- *
+ *
*
*
*
* Mushrooms
- *
+ *
*
*
*
* ```
+ *
* @demo /docs/v2/demos/toggle/
* @see {@link /docs/v2/components#toggle Toggle Component Docs}
*/
@Component({
- selector: 'ion-toggle,ion-switch',
+ selector: 'ion-toggle',
template:
'