chore(components): ngmodule updates

This commit is contained in:
Adam Bradley
2016-09-13 17:07:33 -05:00
parent 16df3a4aab
commit 52ada1ca6d
50 changed files with 927 additions and 790 deletions

View File

@ -1,15 +1,12 @@
import { Component, Renderer, ElementRef, HostListener, ViewEncapsulation } from '@angular/core';
import { NgClass, NgFor, NgIf } from '@angular/common';
import { Animation } from '../../animations/animation';
import { Backdrop } from '../backdrop/backdrop';
import { Config } from '../../config/config';
import { Form } from '../../util/form';
import { Icon } from '../icon/icon';
import { Key } from '../../util/key';
import { NavParams } from '../nav/nav-params';
import { Transition, TransitionOptions } from '../../transitions/transition';
import { ViewController } from '../nav/view-controller';
import { NavParams } from '../../navigation/nav-params';
import { Transition } from '../../transitions/transition';
import { ViewController } from '../../navigation/view-controller';
/**
@ -17,28 +14,26 @@ import { ViewController } from '../nav/view-controller';
*/
@Component({
selector: 'ion-action-sheet',
template: `
<ion-backdrop (click)="bdClick()"></ion-backdrop>
<div class="action-sheet-wrapper">
<div class="action-sheet-container">
<div class="action-sheet-group">
<div class="action-sheet-title" id="{{hdrId}}" *ngIf="d.title">{{d.title}}</div>
<div class="action-sheet-sub-title" id="{{descId}}" *ngIf="d.subTitle">{{d.subTitle}}</div>
<button ion-button="action-sheet-button" (click)="click(b)" *ngFor="let b of d.buttons" class="disable-hover" [ngClass]="b.cssClass">
<ion-icon [name]="b.icon" *ngIf="b.icon" class="action-sheet-icon"></ion-icon>
{{b.text}}
</button>
</div>
<div class="action-sheet-group" *ngIf="d.cancelButton">
<button ion-button="action-sheet-button" (click)="click(d.cancelButton)" class="action-sheet-cancel disable-hover" [ngClass]="d.cancelButton.cssClass">
<ion-icon [name]="d.cancelButton.icon" *ngIf="d.cancelButton.icon" class="action-sheet-icon"></ion-icon>
{{d.cancelButton.text}}
</button>
</div>
</div>
</div>
`,
directives: [Backdrop, Icon, NgClass, NgFor, NgIf],
template:
'<ion-backdrop (click)="bdClick()"></ion-backdrop>' +
'<div class="action-sheet-wrapper">' +
'<div class="action-sheet-container">' +
'<div class="action-sheet-group">' +
'<div class="action-sheet-title" id="{{hdrId}}" *ngIf="d.title">{{d.title}}</div>' +
'<div class="action-sheet-sub-title" id="{{descId}}" *ngIf="d.subTitle">{{d.subTitle}}</div>' +
'<button ion-button="action-sheet-button" (click)="click(b)" *ngFor="let b of d.buttons" class="disable-hover" [ngClass]="b.cssClass">' +
'<ion-icon [name]="b.icon" *ngIf="b.icon" class="action-sheet-icon"></ion-icon>' +
'{{b.text}}' +
'</button>' +
'</div>' +
'<div class="action-sheet-group" *ngIf="d.cancelButton">' +
'<button ion-button="action-sheet-button" (click)="click(d.cancelButton)" class="action-sheet-cancel disable-hover" [ngClass]="d.cancelButton.cssClass">' +
'<ion-icon [name]="d.cancelButton.icon" *ngIf="d.cancelButton.icon" class="action-sheet-icon"></ion-icon>' +
'{{d.cancelButton.text}}' +
'</button>' +
'</div>' +
'</div>' +
'</div>',
host: {
'role': 'dialog',
'[attr.aria-labelledby]': 'hdrId',
@ -47,7 +42,7 @@ import { ViewController } from '../nav/view-controller';
encapsulation: ViewEncapsulation.None,
})
export class ActionSheetCmp {
private d: {
d: {
title?: string;
subTitle?: string;
cssClass?: string;
@ -55,10 +50,11 @@ export class ActionSheetCmp {
enableBackdropDismiss?: boolean;
cancelButton: any;
};
private descId: string;
private enabled: boolean;
private hdrId: string;
private id: number;
descId: string;
enabled: boolean;
hdrId: string;
id: number;
mode: string;
constructor(
private _viewCtrl: ViewController,
@ -69,6 +65,8 @@ export class ActionSheetCmp {
renderer: Renderer
) {
this.d = params.data;
this.mode = _config.get('mode');
renderer.setElementClass(_elementRef.nativeElement, `action-sheet-${this.mode}`, true);
if (this.d.cssClass) {
this.d.cssClass.split(' ').forEach(cssClass => {
@ -86,7 +84,7 @@ export class ActionSheetCmp {
}
}
ionViewLoaded() {
ionViewDidLoad() {
// normalize the data
let buttons: any[] = [];
@ -125,7 +123,7 @@ export class ActionSheetCmp {
}
@HostListener('body:keyup', ['$event'])
private _keyUp(ev: KeyboardEvent) {
keyUp(ev: KeyboardEvent) {
if (this.enabled && this._viewCtrl.isLast()) {
if (ev.keyCode === Key.ESCAPE) {
console.debug('actionsheet, escape button');
@ -174,10 +172,8 @@ export class ActionSheetCmp {
class ActionSheetSlideIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
init() {
let ele = this.enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.action-sheet-wrapper'));
@ -191,10 +187,8 @@ Transition.register('action-sheet-slide-in', ActionSheetSlideIn);
class ActionSheetSlideOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
init() {
let ele = this.leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.action-sheet-wrapper'));
@ -208,10 +202,8 @@ Transition.register('action-sheet-slide-out', ActionSheetSlideOut);
class ActionSheetMdSlideIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
init() {
let ele = this.enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.action-sheet-wrapper'));
@ -225,10 +217,8 @@ Transition.register('action-sheet-md-slide-in', ActionSheetMdSlideIn);
class ActionSheetMdSlideOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
init() {
let ele = this.leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.action-sheet-wrapper'));
@ -241,10 +231,8 @@ class ActionSheetMdSlideOut extends Transition {
Transition.register('action-sheet-md-slide-out', ActionSheetMdSlideOut);
class ActionSheetWpSlideIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
init() {
let ele = this.enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.action-sheet-wrapper'));
@ -258,10 +246,8 @@ Transition.register('action-sheet-wp-slide-in', ActionSheetWpSlideIn);
class ActionSheetWpSlideOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
init() {
let ele = this.leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.action-sheet-wrapper'));

View File

@ -4,8 +4,8 @@ import { ActionSheetCmp } from './action-sheet-component';
import { ActionSheetOptions } from './action-sheet-options';
import { App } from '../app/app';
import { isPresent } from '../../util/util';
import { NavOptions } from '../nav/nav-interfaces';
import { ViewController } from '../nav/view-controller';
import { NavOptions } from '../../navigation/nav-util';
import { ViewController } from '../../navigation/view-controller';
/**
* @private
@ -17,14 +17,9 @@ export class ActionSheet extends ViewController {
opts.buttons = opts.buttons || [];
opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
super(ActionSheetCmp, opts);
super(ActionSheetCmp, opts, null);
this._app = app;
this.isOverlay = true;
// by default, actionsheets should not fire lifecycle events of other views
// for example, when an actionsheets enters, the current active view should
// not fire its lifecycle events because it's not conceptually leaving
this.fireOtherLifecycles = false;
}
/**
@ -70,7 +65,7 @@ export class ActionSheet extends ViewController {
* @private
* DEPRECATED: Please inject ActionSheetController instead
*/
private static create(opt: any) {
static create(opt: any) {
// deprecated warning: added beta.11 2016-06-27
console.warn('ActionSheet.create(..) has been deprecated. Please inject ActionSheetController instead');
}

View File

@ -1,15 +1,12 @@
import { Component, ElementRef, HostListener, Renderer, ViewEncapsulation } from '@angular/core';
import { NgClass, NgFor, NgIf, NgSwitch, NgSwitchCase, NgSwitchDefault } from '@angular/common';
import { NgModel } from '@angular/forms';
import { Animation } from '../../animations/animation';
import { Backdrop } from '../backdrop/backdrop';
import { Config } from '../../config/config';
import { isPresent } from '../../util/util';
import { Key } from '../../util/key';
import { NavParams } from '../nav/nav-params';
import { Transition, TransitionOptions } from '../../transitions/transition';
import { ViewController } from '../nav/view-controller';
import { NavParams } from '../../navigation/nav-params';
import { Transition } from '../../transitions/transition';
import { ViewController } from '../../navigation/view-controller';
/**
@ -17,55 +14,53 @@ import { ViewController } from '../nav/view-controller';
*/
@Component({
selector: 'ion-alert',
template: `
<ion-backdrop (click)="bdClick()"></ion-backdrop>
<div class="alert-wrapper">
<div class="alert-head">
<h2 id="{{hdrId}}" class="alert-title" *ngIf="d.title" [innerHTML]="d.title"></h2>
<h3 id="{{subHdrId}}" class="alert-sub-title" *ngIf="d.subTitle" [innerHTML]="d.subTitle"></h3>
</div>
<div id="{{msgId}}" class="alert-message" [innerHTML]="d.message"></div>
<div *ngIf="d.inputs.length" [ngSwitch]="inputType">
template:
'<ion-backdrop (click)="bdClick()"></ion-backdrop>' +
'<div class="alert-wrapper">' +
'<div class="alert-head">' +
'<h2 id="{{hdrId}}" class="alert-title" *ngIf="d.title" [innerHTML]="d.title"></h2>' +
'<h3 id="{{subHdrId}}" class="alert-sub-title" *ngIf="d.subTitle" [innerHTML]="d.subTitle"></h3>' +
'</div>' +
'<div id="{{msgId}}" class="alert-message" [innerHTML]="d.message"></div>' +
'<div *ngIf="d.inputs.length" [ngSwitch]="inputType">' +
<template ngSwitchCase="radio">
<div class="alert-radio-group" role="radiogroup" [attr.aria-labelledby]="hdrId" [attr.aria-activedescendant]="activeId">
<button ion-button="alert-radio-button" *ngFor="let i of d.inputs" (click)="rbClick(i)" [attr.aria-checked]="i.checked" [disabled]="i.disabled" [attr.id]="i.id" class="alert-tappable alert-radio" role="radio">
<div class="alert-radio-icon"><div class="alert-radio-inner"></div></div>
<div class="alert-radio-label">
{{i.label}}
</div>
</button>
</div>
</template>
'<template ngSwitchCase="radio">' +
'<div class="alert-radio-group" role="radiogroup" [attr.aria-labelledby]="hdrId" [attr.aria-activedescendant]="activeId">' +
'<button ion-button="alert-radio-button" *ngFor="let i of d.inputs" (click)="rbClick(i)" [attr.aria-checked]="i.checked" [disabled]="i.disabled" [attr.id]="i.id" class="alert-tappable alert-radio" role="radio">' +
'<div class="alert-radio-icon"><div class="alert-radio-inner"></div></div>' +
'<div class="alert-radio-label">' +
'{{i.label}}' +
'</div>' +
'</button>' +
'</div>' +
'</template>' +
<template ngSwitchCase="checkbox">
<div class="alert-checkbox-group">
<button ion-button="alert-checkbox-button" *ngFor="let i of d.inputs" (click)="cbClick(i)" [attr.aria-checked]="i.checked" [disabled]="i.disabled" class="alert-tappable alert-checkbox" role="checkbox">
<div class="alert-checkbox-icon"><div class="alert-checkbox-inner"></div></div>
<div class="alert-checkbox-label">
{{i.label}}
</div>
</button>
</div>
</template>
'<template ngSwitchCase="checkbox">' +
'<div class="alert-checkbox-group">' +
'<button ion-button="alert-checkbox-button" *ngFor="let i of d.inputs" (click)="cbClick(i)" [attr.aria-checked]="i.checked" [disabled]="i.disabled" class="alert-tappable alert-checkbox" role="checkbox">' +
'<div class="alert-checkbox-icon"><div class="alert-checkbox-inner"></div></div>' +
'<div class="alert-checkbox-label">' +
'{{i.label}}' +
'</div>' +
'</button>' +
'</div>' +
'</template>' +
<template ngSwitchDefault>
<div class="alert-input-group">
<div *ngFor="let i of d.inputs" class="alert-input-wrapper">
<input [placeholder]="i.placeholder" [(ngModel)]="i.value" [type]="i.type" class="alert-input">
</div>
</div>
</template>
'<template ngSwitchDefault>' +
'<div class="alert-input-group">' +
'<div *ngFor="let i of d.inputs" class="alert-input-wrapper">' +
'<input [placeholder]="i.placeholder" [(ngModel)]="i.value" [type]="i.type" class="alert-input">' +
'</div>' +
'</div>' +
'</template>' +
</div>
<div class="alert-button-group" [ngClass]="{vertical: d.buttons.length>2}">
<button ion-button="alert-button" *ngFor="let b of d.buttons" (click)="btnClick(b)" [ngClass]="b.cssClass">
{{b.text}}
</button>
</div>
</div>
`,
directives: [Backdrop, NgClass, NgFor, NgIf, NgModel, NgSwitch, NgSwitchCase, NgSwitchDefault],
'</div>' +
'<div class="alert-button-group" [ngClass]="{\'alert-button-group-vertical\':d.buttons.length>2}">' +
'<button ion-button="alert-button" *ngFor="let b of d.buttons" (click)="btnClick(b)" [ngClass]="b.cssClass">' +
'{{b.text}}' +
'</button>' +
'</div>' +
'</div>',
host: {
'role': 'dialog',
'[attr.aria-labelledby]': 'hdrId',
@ -74,32 +69,36 @@ import { ViewController } from '../nav/view-controller';
encapsulation: ViewEncapsulation.None,
})
export class AlertCmp {
private activeId: string;
private descId: string;
private d: {
activeId: string;
descId: string;
d: {
cssClass?: string;
message?: string;
title?: string;
subTitle?: string;
buttons?: any[];
inputs?: any[];
enableBackdropDismiss?: boolean;
};
private enabled: boolean;
private hdrId: string;
private id: number;
private inputType: string;
private lastClick: number;
private msgId: string;
private subHdrId: string;
enabled: boolean;
hdrId: string;
id: number;
inputType: string;
lastClick: number;
msgId: string;
subHdrId: string;
mode: string;
constructor(
private _viewCtrl: ViewController,
private _elementRef: ElementRef,
private _config: Config,
public _viewCtrl: ViewController,
public _elementRef: ElementRef,
public _config: Config,
params: NavParams,
renderer: Renderer
) {
this.d = params.data;
this.mode = _config.get('mode');
renderer.setElementClass(_elementRef.nativeElement, `alert-${this.mode}`, true);
if (this.d.cssClass) {
this.d.cssClass.split(' ').forEach(cssClass => {
@ -128,7 +127,7 @@ export class AlertCmp {
}
}
ionViewLoaded() {
ionViewDidLoad() {
// normalize the data
let data = this.d;
@ -175,7 +174,7 @@ export class AlertCmp {
}
@HostListener('body:keyup', ['$event'])
private _keyUp(ev: KeyboardEvent) {
keyUp(ev: KeyboardEvent) {
if (this.enabled && this._viewCtrl.isLast()) {
if (ev.keyCode === Key.ENTER) {
if (this.lastClick + 1000 < Date.now()) {
@ -294,10 +293,8 @@ export class AlertCmp {
* Animations for alerts
*/
class AlertPopIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
init() {
let ele = this.enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.alert-wrapper'));
@ -315,10 +312,8 @@ Transition.register('alert-pop-in', AlertPopIn);
class AlertPopOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
init() {
let ele = this.leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.alert-wrapper'));
@ -336,10 +331,8 @@ Transition.register('alert-pop-out', AlertPopOut);
class AlertMdPopIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
init() {
let ele = this.enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.alert-wrapper'));
@ -357,10 +350,8 @@ Transition.register('alert-md-pop-in', AlertMdPopIn);
class AlertMdPopOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
init() {
let ele = this.leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.alert-wrapper'));
@ -377,12 +368,9 @@ class AlertMdPopOut extends Transition {
Transition.register('alert-md-pop-out', AlertMdPopOut);
class AlertWpPopIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
init() {
let ele = this.enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.alert-wrapper'));
@ -400,10 +388,8 @@ Transition.register('alert-wp-pop-in', AlertWpPopIn);
class AlertWpPopOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
init() {
let ele = this.leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.alert-wrapper'));

View File

@ -4,8 +4,8 @@ import { App } from '../app/app';
import { AlertCmp } from './alert-component';
import { AlertOptions, AlertInputOptions } from './alert-options';
import { isPresent } from '../../util/util';
import { NavOptions } from '../nav/nav-interfaces';
import { ViewController } from '../nav/view-controller';
import { NavOptions } from '../../navigation/nav-util';
import { ViewController } from '../../navigation/view-controller';
/**
@ -19,14 +19,9 @@ export class Alert extends ViewController {
opts.buttons = opts.buttons || [];
opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
super(AlertCmp, opts);
super(AlertCmp, opts, null);
this._app = app;
this.isOverlay = true;
// by default, alerts should not fire lifecycle events of other views
// for example, when an alert enters, the current active view should
// not fire its lifecycle events because it's not conceptually leaving
this.fireOtherLifecycles = false;
}
/**
@ -51,15 +46,6 @@ export class Alert extends ViewController {
this.data.subTitle = subTitle;
}
/**
* @private
*/
private setBody(message: string) {
// deprecated warning
console.warn('Alert setBody() has been renamed to setMessage()');
this.setMessage(message);
}
/**
* @param {string} message Alert message content
*/
@ -102,7 +88,7 @@ export class Alert extends ViewController {
* @private
* DEPRECATED: Please inject AlertController instead
*/
private static create(opt: any) {
static create(opt: any) {
// deprecated warning: added beta.11 2016-06-27
console.warn('Alert.create(..) has been deprecated. Please inject AlertController instead');
}

View File

@ -0,0 +1,13 @@
import { Directive } from '@angular/core';
/**
* @name Avatar
* @module ionic
* @description
*/
@Directive({
selector: 'ion-avatar'
})
export class Avatar {
}

View File

@ -1,6 +1,6 @@
import { Directive, ElementRef, Input } from '@angular/core';
import { DisableScroll, GestureController, GestureDelegate } from '../../gestures/gesture-controller';
import { GestureController } from '../../gestures/gesture-controller';
import { isTrueProperty } from '../../util/util';

View File

@ -0,0 +1,63 @@
import { Directive, ElementRef, Input, Renderer } from '@angular/core';
import { Config } from '../../config/config';
import { Ion } from '../ion';
/**
* @private
*/
@Directive({
selector: 'ion-card'
})
export class Card extends Ion {
/**
* @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`.
*/
@Input()
set color(val: string) {
this._setColor('card', val);
}
/**
* @input {string} The mode to apply to this component.
*/
@Input()
set mode(val: string) {
this._setMode('card', val);
}
constructor(config: Config, elementRef: ElementRef, renderer: Renderer) {
super(config, elementRef, renderer);
this.mode = config.get('mode');
}
}
/**
* @private
*/
@Directive({
selector: 'ion-card-content'
})
export class CardContent {}
/**
* @private
*/
@Directive({
selector: 'ion-card-header'
})
export class CardHeader {}
/**
* @private
*/
@Directive({
selector: 'ion-card-title'
})
export class CardTitle {}

View File

@ -0,0 +1,13 @@
import { Directive } from '@angular/core';
/**
* @name Fixed
* @module ionic
* @description
*/
@Directive({
selector: 'ion-fixed'
})
export class Fixed {
}

View File

@ -0,0 +1,37 @@
import { Directive } from '@angular/core';
/**
* @name Grid
* @module ionic
* @description
*/
@Directive({
selector: 'ion-grid'
})
export class Grid {
}
/**
* @name Row
* @module ionic
* @description
*/
@Directive({
selector: 'ion-row'
})
export class Row {
}
/**
* @name Column
* @module ionic
* @description
*/
@Directive({
selector: 'ion-col'
})
export class Col {
}

View File

View File

@ -16,13 +16,13 @@ import { Platform } from '../../platform/platform';
encapsulation: ViewEncapsulation.None,
})
export class Img {
private _src: string = '';
private _normalizeSrc: string = '';
private _imgs: HTMLImageElement[] = [];
private _w: string;
private _h: string;
private _enabled: boolean = true;
private _init: boolean;
_src: string = '';
_normalizeSrc: string = '';
_imgs: HTMLImageElement[] = [];
_w: string;
_h: string;
_enabled: boolean = true;
_init: boolean;
constructor(private _elementRef: ElementRef, private _platform: Platform, private _zone: NgZone) {}
@ -44,7 +44,7 @@ export class Img {
this._update();
}
private _update() {
_update() {
if (this._enabled && this._src !== '') {
// actively update the image
@ -101,7 +101,7 @@ export class Img {
}
}
private _loaded(isLoaded: boolean) {
_loaded(isLoaded: boolean) {
this._elementRef.nativeElement.classList[isLoaded ? 'add' : 'remove']('img-loaded');
}

View File

@ -1,9 +1,7 @@
import { Component, Input, ViewEncapsulation } from '@angular/core';
import { NgIf } from '@angular/common';
import { Config } from '../../config/config';
import { InfiniteScroll } from './infinite-scroll';
import { Spinner } from '../spinner/spinner';
/**
@ -18,7 +16,6 @@ import { Spinner } from '../spinner/spinner';
'</div>' +
'<div class="infinite-loading-text" [innerHTML]="loadingText" *ngIf="loadingText"></div>' +
'</div>',
directives: [NgIf, Spinner],
host: {
'[attr.state]': 'inf.state'
},
@ -36,7 +33,7 @@ export class InfiniteScrollContent {
*/
@Input() loadingText: string;
constructor(private inf: InfiniteScroll, private _config: Config) {}
constructor(public inf: InfiniteScroll, private _config: Config) {}
/**
* @private

View File

@ -95,13 +95,13 @@ import { Content } from '../content/content';
selector: 'ion-infinite-scroll'
})
export class InfiniteScroll {
private _lastCheck: number = 0;
private _highestY: number = 0;
private _scLsn: Function;
private _thr: string = '15%';
private _thrPx: number = 0;
private _thrPc: number = 0.15;
private _init: boolean = false;
_lastCheck: number = 0;
_highestY: number = 0;
_scLsn: Function;
_thr: string = '15%';
_thrPx: number = 0;
_thrPc: number = 0.15;
_init: boolean = false;
state: string = STATE_ENABLED;
@ -144,10 +144,10 @@ export class InfiniteScroll {
private _zone: NgZone,
private _elementRef: ElementRef
) {
_content.addCssClass('has-infinite-scroll');
_content.setElementClass('has-infinite-scroll', true);
}
private _onScroll() {
_onScroll() {
if (this.state === STATE_LOADING || this.state === STATE_DISABLED) {
return 1;
}
@ -217,7 +217,7 @@ export class InfiniteScroll {
this._setListeners(shouldEnable);
}
private _setListeners(shouldListen: boolean) {
_setListeners(shouldListen: boolean) {
if (this._init) {
if (shouldListen) {
if (!this._scLsn) {

View File

@ -1,7 +1,6 @@
import { Item } from './item';
import { PointerCoordinates, CSS, pointerCoord } from '../../util/dom';
import { ItemReorder, indexForItem, findReorderItem } from '../item/item-reorder';
import { UIEventManager } from '../../util/ui-event-manager';
import { closest, Coordinates, pointerCoord, CSS, nativeRaf } from '../../util/dom';
const AUTO_SCROLL_MARGIN = 60;
@ -15,7 +14,7 @@ export class ItemReorderGesture {
private selectedItemEle: HTMLElement = null;
private selectedItemHeight: number;
private offset: Coordinates;
private offset: PointerCoordinates;
private lastToIndex: number;
private lastYcoord: number;
private lastScrollPosition: number;
@ -104,7 +103,7 @@ export class ItemReorderGesture {
// Update selected item position
let ydiff = Math.round(posY - this.offset.y + scrollPosition);
selectedItem.style[CSS.transform] = `translateY(${ydiff}px)`;
(<any>selectedItem.style)[CSS.transform] = `translateY(${ydiff}px)`;
}
private onDragEnd() {
@ -129,7 +128,7 @@ export class ItemReorderGesture {
this.reorderList.reorderEmit(fromIndex, toIndex);
}
private itemForCoord(coord: Coordinates): HTMLElement {
private itemForCoord(coord: PointerCoordinates): HTMLElement {
return itemForPosition(this.offset.x - 100, coord.y);
}

View File

@ -129,15 +129,24 @@ export interface ReorderIndexes {
host: {
'[class.reorder-enabled]': '_enableReorder',
'[class.reorder-visible]': '_visibleReorder',
}
})
export class ItemReorder {
private _enableReorder: boolean = false;
private _visibleReorder: boolean = false;
private _reorderGesture: ItemReorderGesture;
private _lastToIndex: number = -1;
private _element: HTMLElement;
/** @private */
_enableReorder: boolean = false;
/** @private */
_visibleReorder: boolean = false;
/** @private */
_reorderGesture: ItemReorderGesture;
/** @private */
_lastToIndex: number = -1;
/** @private */
_element: HTMLElement;
/**
* @output {object} The expression to evaluate when the item is reordered. Emits an object
@ -191,10 +200,9 @@ export class ItemReorder {
* @private
*/
reorderPrepare() {
let children = this._element.children;
let len = children.length;
for (let i = 0; i < len; i++) {
children[i]['$ionIndex'] = i;
let children: any = this._element.children;
for (let i = 0, ilen = children.length; i < ilen; i++) {
children[i].$ionIndex = i;
}
}

View File

@ -1,10 +1,9 @@
import { ItemSliding } from './item-sliding';
import { List } from '../list/list';
import { closest, Coordinates, pointerCoord } from '../../util/dom';
import { PointerEvents, UIEventManager } from '../../util/ui-event-manager';
import { GestureDelegate, GestureOptions, GesturePriority } from '../../gestures/gesture-controller';
import { GesturePriority } from '../../gestures/gesture-controller';
import { PanGesture } from '../../gestures/drag-gesture';
import { pointerCoord } from '../../util/dom';
const DRAG_THRESHOLD = 10;
const MAX_ATTACK_ANGLE = 20;
@ -66,10 +65,6 @@ export class ItemSlidingGesture extends PanGesture {
onDragEnd(ev: any) {
ev.preventDefault();
let coordX = pointerCoord(ev).x;
let deltaX = (coordX - this.firstCoordX);
let deltaT = (Date.now() - this.firstTimestamp);
let openAmount = this.selectedContainer.endSliding(deltaX / deltaT);
this.selectedContainer = null;
this.preSelectedContainer = null;
}
@ -101,9 +96,9 @@ export class ItemSlidingGesture extends PanGesture {
}
function getContainer(ev: any): ItemSliding {
let ele = closest(ev.target, 'ion-item-sliding', true);
let ele = ev.target.closest('ion-item-sliding', true);
if (ele) {
return (<any>ele)['$ionComponent'];
}
return null;
}
}

View File

@ -81,7 +81,7 @@ export class ItemOptions {
}
const enum SlidingState {
export const enum SlidingState {
Disabled = 1 << 1,
Enabled = 1 << 2,
Right = 1 << 3,
@ -200,7 +200,7 @@ export class ItemSliding {
/**
* @private
*/
@ContentChild(Item) private item: Item;
@ContentChild(Item) item: Item;
/**
* @output {event} Expression to evaluate when the sliding position changes.
@ -228,11 +228,11 @@ export class ItemSliding {
constructor( @Optional() list: List, private _renderer: Renderer, private _elementRef: ElementRef) {
list && list.containsSlidingItem(true);
_elementRef.nativeElement.$ionComponent = this;
this.setCssClass('item-wrapper', true);
this._setCssClass('item-wrapper', true);
}
@ContentChildren(ItemOptions)
private set _itemOptions(itemOptions: QueryList<ItemOptions>) {
set _itemOptions(itemOptions: QueryList<ItemOptions>) {
let sides = 0;
for (var item of itemOptions.toArray()) {
var side = item.getSides();
@ -281,7 +281,7 @@ export class ItemSliding {
this._setState(SlidingState.Enabled);
}
this._startX = startX + this._openAmount;
this.item.setCssStyle(CSS.transition, 'none');
this.item.setElementStyle(CSS.transition, 'none');
}
/**
@ -376,7 +376,7 @@ export class ItemSliding {
this._openAmount = openAmount;
if (isFinal) {
this.item.setCssStyle(CSS.transition, '');
this.item.setElementStyle(CSS.transition, '');
} else {
if (openAmount > 0) {
@ -399,11 +399,11 @@ export class ItemSliding {
this._setState(SlidingState.Disabled);
this._timer = null;
}, 600);
this.item.setCssStyle(CSS.transform, '');
this.item.setElementStyle(CSS.transform, '');
return;
}
this.item.setCssStyle(CSS.transform, `translate3d(${-openAmount}px,0,0)`);
this.item.setElementStyle(CSS.transform, `translate3d(${-openAmount}px,0,0)`);
this.ionDrag.emit(this);
}
@ -411,11 +411,11 @@ export class ItemSliding {
if (state === this._state) {
return;
}
this.setCssClass('active-slide', (state !== SlidingState.Disabled));
this.setCssClass('active-options-right', !!(state & SlidingState.Right));
this.setCssClass('active-options-left', !!(state & SlidingState.Left));
this.setCssClass('active-swipe-right', !!(state & SlidingState.SwipeRight));
this.setCssClass('active-swipe-left', !!(state & SlidingState.SwipeLeft));
this._setCssClass('active-slide', (state !== SlidingState.Disabled));
this._setCssClass('active-options-right', !!(state & SlidingState.Right));
this._setCssClass('active-options-left', !!(state & SlidingState.Left));
this._setCssClass('active-swipe-right', !!(state & SlidingState.SwipeRight));
this._setCssClass('active-swipe-left', !!(state & SlidingState.SwipeLeft));
this._state = state;
}
@ -461,14 +461,14 @@ export class ItemSliding {
/**
* @private
*/
setCssClass(cssClass: string, shouldAdd: boolean) {
_setCssClass(cssClass: string, shouldAdd: boolean) {
this._renderer.setElementClass(this._elementRef.nativeElement, cssClass, shouldAdd);
}
/**
* @private
*/
setCssStyle(property: string, value: string) {
_setCssStyle(property: string, value: string) {
this._renderer.setElementStyle(this._elementRef.nativeElement, property, value);
}
}

View File

@ -0,0 +1,26 @@
import { Attribute, Directive, ElementRef, Renderer } from '@angular/core';
import { Config } from '../../config/config';
import { Ion } from '../ion';
/**
* @private
*/
@Directive({
selector: 'ion-list-header'
})
export class ListHeader extends Ion {
constructor(config: Config, renderer: Renderer, elementRef: ElementRef, @Attribute('id') private _id: string) {
super(config, elementRef, renderer);
this._setMode('list-header', config.get('mode'));
}
get id(): string {
return this._id;
}
set id(val: string) {
this._id = val;
this.setElementAttribute('id', val);
}
}

View File

@ -1,6 +1,6 @@
import { Attribute, Directive, ElementRef, EventEmitter, Input, NgZone, Optional, Output, Renderer } from '@angular/core';
import { Directive, ElementRef, Input, Renderer } from '@angular/core';
import { Content } from '../content/content';
import { Config } from '../../config/config';
import { Ion } from '../ion';
import { isTrueProperty } from '../../util/util';
import { ItemSlidingGesture } from '../item/item-sliding-gesture';
@ -50,17 +50,22 @@ export class List extends Ion {
private _slidingGesture: ItemSlidingGesture;
constructor(
config: Config,
elementRef: ElementRef,
private _rendered: Renderer,
public _gestureCtrl: GestureController) {
super(elementRef);
renderer: Renderer,
public _gestureCtrl: GestureController
) {
super(config, elementRef, renderer);
this.mode = config.get('mode');
}
/**
* @private
* @input {string} The mode to apply to this component.
*/
ngOnDestroy() {
this._slidingGesture && this._slidingGesture.destroy();
@Input()
set mode(val: string) {
this._setMode('list', val);
}
/**
@ -75,7 +80,6 @@ export class List extends Ion {
this._updateSlidingState();
}
/**
* @private
*/
@ -98,31 +102,17 @@ export class List extends Ion {
}
}
/**
* Close any sliding items that are open.
*/
closeSlidingItems() {
this._slidingGesture && this._slidingGesture.closeOpened();
}
}
/**
* @private
*/
@Directive({
selector: 'ion-list-header'
})
export class ListHeader {
constructor(private _renderer: Renderer, private _elementRef: ElementRef, @Attribute('id') private _id: string) { }
public get id(): string {
return this._id;
}
public set id(val: string) {
this._id = val;
this._renderer.setElementAttribute(this._elementRef.nativeElement, 'id', val);
/**
* @private
*/
destroy() {
this._slidingGesture && this._slidingGesture.destroy();
}
}

View File

@ -1,14 +1,11 @@
import { Component, ElementRef, Renderer, ViewEncapsulation } from '@angular/core';
import { NgIf } from '@angular/common';
import { Animation } from '../../animations/animation';
import { Backdrop } from '../backdrop/backdrop';
import { Config } from '../../config/config';
import { isDefined, isPresent, isUndefined } from '../../util/util';
import { NavParams } from '../nav/nav-params';
import { Spinner } from '../spinner/spinner';
import { Transition, TransitionOptions } from '../../transitions/transition';
import { ViewController } from '../nav/view-controller';
import { isDefined, isUndefined } from '../../util/util';
import { NavParams } from '../../navigation/nav-params';
import { Transition } from '../../transitions/transition';
import { ViewController } from '../../navigation/view-controller';
/**
@ -16,23 +13,21 @@ import { ViewController } from '../nav/view-controller';
*/
@Component({
selector: 'ion-loading',
template: `
<ion-backdrop [class.hide-backdrop]="!d.showBackdrop"></ion-backdrop>
<div class="loading-wrapper">
<div *ngIf="showSpinner" class="loading-spinner">
<ion-spinner [name]="d.spinner"></ion-spinner>
</div>
<div *ngIf="d.content" [innerHTML]="d.content" class="loading-content"></div>
</div>
`,
directives: [Backdrop, NgIf, Spinner],
template:
'<ion-backdrop [class.hide-backdrop]="!d.showBackdrop"></ion-backdrop>' +
'<div class="loading-wrapper">' +
'<div *ngIf="showSpinner" class="loading-spinner">' +
'<ion-spinner [name]="d.spinner"></ion-spinner>' +
'</div>' +
'<div *ngIf="d.content" [innerHTML]="d.content" class="loading-content"></div>' +
'</div>',
host: {
'role': 'dialog'
},
encapsulation: ViewEncapsulation.None,
})
export class LoadingCmp {
private d: {
d: {
spinner?: string;
content?: string;
cssClass?: string;
@ -41,9 +36,9 @@ export class LoadingCmp {
delay?: number;
duration?: number;
};
private id: number;
private showSpinner: boolean;
private durationTimeout: number;
id: number;
showSpinner: boolean;
durationTimeout: number;
constructor(
private _viewCtrl: ViewController,
@ -54,6 +49,8 @@ export class LoadingCmp {
) {
this.d = params.data;
renderer.setElementClass(_elementRef.nativeElement, `loading-${_config.get('mode')}`, true);
if (this.d.cssClass) {
this.d.cssClass.split(' ').forEach(cssClass => {
// Make sure the class isn't whitespace, otherwise it throws exceptions
@ -82,7 +79,12 @@ export class LoadingCmp {
}
// If there is a duration, dismiss after that amount of time
this.d.duration ? this.durationTimeout = setTimeout(() => this.dismiss('backdrop'), this.d.duration) : null;
if ( this.d && this.d.duration ) {
this.durationTimeout = (<any> setTimeout( () => {
this.dismiss('backdrop');
}, this.d.duration));
}
}
dismiss(role: any): Promise<any> {
@ -98,10 +100,8 @@ export class LoadingCmp {
* Animations for loading
*/
class LoadingPopIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
init() {
let ele = this.enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.loading-wrapper'));
@ -119,10 +119,8 @@ export class LoadingCmp {
class LoadingPopOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
init() {
let ele = this.leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.loading-wrapper'));
@ -140,10 +138,8 @@ export class LoadingCmp {
class LoadingMdPopIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
init() {
let ele = this.enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.loading-wrapper'));
@ -161,10 +157,8 @@ export class LoadingCmp {
class LoadingMdPopOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
init() {
let ele = this.leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.loading-wrapper'));
@ -182,10 +176,8 @@ export class LoadingCmp {
class LoadingWpPopIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
init() {
let ele = this.enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.loading-wrapper'));
@ -203,10 +195,8 @@ export class LoadingCmp {
class LoadingWpPopOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
init() {
let ele = this.leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.loading-wrapper'));

View File

@ -1,12 +1,12 @@
import { Injectable } from '@angular/core';
import { App } from '../app/app';
import { Config } from '../../config/config';
import { AppPortal } from '../app/app-root';
import { isPresent } from '../../util/util';
import { LoadingCmp } from './loading-component';
import { LoadingOptions } from './loading-options';
import { NavOptions } from '../nav/nav-interfaces';
import { ViewController } from '../nav/view-controller';
import { NavOptions } from '../../navigation/nav-util';
import { ViewController } from '../../navigation/view-controller';
/**
* @private
@ -18,14 +18,9 @@ export class Loading extends ViewController {
opts.showBackdrop = isPresent(opts.showBackdrop) ? !!opts.showBackdrop : true;
opts.dismissOnPageChange = isPresent(opts.dismissOnPageChange) ? !!opts.dismissOnPageChange : false;
super(LoadingCmp, opts);
super(LoadingCmp, opts, null);
this._app = app;
this.isOverlay = true;
// by default, loading indicators should not fire lifecycle events of other views
// for example, when an loading indicators enters, the current active view should
// not fire its lifecycle events because it's not conceptually leaving
this.fireOtherLifecycles = false;
}
/**
@ -43,7 +38,6 @@ export class Loading extends ViewController {
this.data.content = content;
}
/**
* Present the loading instance.
*
@ -51,14 +45,21 @@ export class Loading extends ViewController {
* @returns {Promise} Returns a promise which is resolved when the transition has completed.
*/
present(navOptions: NavOptions = {}) {
return this._app.present(this, navOptions);
return this._app.present(this, navOptions, AppPortal.LOADING);
}
/**
* Dismiss all loading components which have been presented.
*/
dismissAll() {
this._nav && this._nav.popAll();
}
/**
* @private
* DEPRECATED: Please inject LoadingController instead
*/
private static create(opt: any) {
static create(opt: any) {
// deprecated warning: added beta.11 2016-06-27
console.warn('Loading.create(..) has been deprecated. Please inject LoadingController instead');
}
@ -108,7 +109,7 @@ export class Loading extends ViewController {
*
* @usage
* ```ts
* constructor(private loadingCtrl: LoadingController) {
* constructor(public loadingCtrl: LoadingController) {
*
* }
*

View File

@ -44,7 +44,7 @@ export class MenuClose {
*/
@HostListener('click')
close() {
let menu = this._menu.get(this.menuClose);
const menu = this._menu.get(this.menuClose);
menu && menu.close();
}

View File

@ -77,11 +77,11 @@ import { Platform } from '../../platform/platform';
*
* ```ts
* toggleLeftMenu() {
* this.menu.toggle();
* this.menuCtrl.toggle();
* }
*
* toggleRightMenu() {
* this.menu.toggle('right');
* this.menuCtrl.toggle('right');
* }
* ```
*
@ -101,8 +101,8 @@ import { Platform } from '../../platform/platform';
*
* ```ts
* enableAuthenticatedMenu() {
* this.menu.enable(true, 'authenticated');
* this.menu.enable(false, 'unauthenticated');
* this.menuCtrl.enable(true, 'authenticated');
* this.menuCtrl.enable(false, 'unauthenticated');
* }
* ```
*

View File

@ -2,7 +2,7 @@ import { Directive, ElementRef, Input, HostListener, Optional } from '@angular/c
import { MenuController } from './menu-controller';
import { Navbar } from '../navbar/navbar';
import { ViewController } from '../nav/view-controller';
import { ViewController } from '../../navigation/view-controller';
/**
* @name MenuToggle

View File

@ -2,7 +2,6 @@ import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, Ng
import { Backdrop } from '../backdrop/backdrop';
import { Config } from '../../config/config';
import { Ion } from '../ion';
import { isTrueProperty } from '../../util/util';
import { Keyboard } from '../../util/keyboard';
import { MenuContentGesture } from './menu-gestures';
@ -177,14 +176,12 @@ import { GestureController } from '../../gestures/gesture-controller';
*/
@Component({
selector: 'ion-menu',
template:
'<div class="menu-inner"><ng-content></ng-content></div>' +
'<ion-backdrop (click)="bdClick($event)" disableScroll="false"></ion-backdrop>',
host: {
'role': 'navigation'
},
template: `
<div class="menu-inner"><ng-content></ng-content></div>
<ion-backdrop (click)="bdClick($event)" disableScroll="false"></ion-backdrop>
`,
directives: [Backdrop],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
@ -294,8 +291,11 @@ export class Menu {
*/
@Output() ionClose: EventEmitter<boolean> = new EventEmitter<boolean>();
/** @private */
_menuCtrl: MenuController;
constructor(
private _menuCtrl: MenuController,
_menuCtrl: MenuController,
private _elementRef: ElementRef,
private _config: Config,
private _platform: Platform,
@ -303,7 +303,9 @@ export class Menu {
private _keyboard: Keyboard,
private _zone: NgZone,
public gestureCtrl: GestureController
) { }
) {
this._menuCtrl = _menuCtrl;
}
/**
* @private
@ -496,7 +498,7 @@ export class Menu {
this.isOpen = isOpen;
this._cntEle.classList[isOpen ? 'add' : 'remove']('menu-content-open');
(<any>this._cntEle.classList)[isOpen ? 'add' : 'remove']('menu-content-open');
this._cntEle.removeEventListener('click', this.onContentClick);
@ -557,10 +559,9 @@ export class Menu {
// if this menu should be enabled
// then find all the other menus on this same side
// and automatically disable other same side menus
let sameSideMenus = this._menuCtrl
.getMenus()
.filter(m => m.side === this.side && m !== this)
.map(m => m.enabled = false);
this._menuCtrl.getMenus()
.filter(m => m.side === this.side && m !== this)
.map(m => m.enabled = false);
}
return this;

View File

@ -4,8 +4,8 @@ import { App } from '../app/app';
import { isPresent } from '../../util/util';
import { ModalCmp } from './modal-component';
import { ModalOptions } from './modal-options';
import { NavOptions } from '../nav/nav-interfaces';
import { ViewController } from '../nav/view-controller';
import { NavOptions } from '../../navigation/nav-util';
import { ViewController } from '../../navigation/view-controller';
/**
@ -14,13 +14,13 @@ import { ViewController } from '../nav/view-controller';
export class Modal extends ViewController {
private _app: App;
constructor(app: App, componentType: any, data: any = {}, opts: ModalOptions = {}) {
data.componentType = componentType;
constructor(app: App, component: any, data: any = {}, opts: ModalOptions = {}) {
data.component = component;
opts.showBackdrop = isPresent(opts.showBackdrop) ? !!opts.showBackdrop : true;
opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
data.opts = opts;
super(ModalCmp, data);
super(ModalCmp, data, null);
this._app = app;
this.isOverlay = true;
}
@ -33,22 +33,6 @@ export class Modal extends ViewController {
return this._nav && this._nav.config.get(key);
}
/**
* @private
* Override the load method and load our child component
*/
loaded(done: Function) {
// grab the instance, and proxy the ngAfterViewInit method
let originalNgAfterViewInit = this.instance.ngAfterViewInit;
this.instance.ngAfterViewInit = () => {
if (originalNgAfterViewInit) {
originalNgAfterViewInit();
}
this.instance.loadComponent(done);
};
}
/**
* Present the action sheet instance.
*
@ -63,7 +47,7 @@ export class Modal extends ViewController {
* @private
* DEPRECATED: Please inject ModalController instead
*/
private static create(cmp: any, opt: any) {
static create(cmp: any, opt: any) {
// deprecated warning: added beta.11 2016-06-27
console.warn('Modal.create(..) has been deprecated. Please inject ModalController instead');
}
@ -184,11 +168,11 @@ export class ModalController {
/**
* Create a modal to display. See below for options.
*
* @param {object} componentType The Modal view
* @param {object} component The Modal view
* @param {object} data Any data to pass to the Modal view
* @param {object} opts Modal options
*/
create(componentType: any, data: any = {}, opts: ModalOptions = {}) {
return new Modal(this._app, componentType, data, opts);
create(component: any, data: any = {}, opts: ModalOptions = {}) {
return new Modal(this._app, component, data, opts);
}
}

View File

@ -0,0 +1,10 @@
import { Directive } from '@angular/core';
/**
* @private
*/
@Directive({
selector: 'ion-note'
})
export class Note {}

View File

@ -13,9 +13,9 @@ import { isPresent, isTrueProperty } from '../../util/util';
selector: 'ion-option'
})
export class Option {
private _selected: any = false;
private _disabled: any = false;
private _value: any;
_selected: any = false;
_disabled: any = false;
_value: any;
/**
* @input {any} Event to evaluate when option is selected

View File

@ -1,19 +1,17 @@
import { Component, ElementRef, EventEmitter, Input, HostListener, Output, QueryList, Renderer, ViewChild, ViewChildren, ViewEncapsulation } from '@angular/core';
import { NgClass, NgFor, NgIf } from '@angular/common';
import { DomSanitizationService } from '@angular/platform-browser';
import { DomSanitizer } from '@angular/platform-browser';
import { Animation } from '../../animations/animation';
import { Backdrop } from '../backdrop/backdrop';
import { cancelRaf, pointerCoord, raf } from '../../util/dom';
import { clamp, isNumber, isPresent, isString } from '../../util/util';
import { Config } from '../../config/config';
import { Key } from '../../util/key';
import { NavParams } from '../nav/nav-params';
import { NavParams } from '../../navigation/nav-params';
import { Picker } from './picker';
import { PickerOptions, PickerColumn, PickerColumnOption } from './picker-options';
import { Transition, TransitionOptions } from '../../transitions/transition';
import { Transition } from '../../transitions/transition';
import { UIEventManager } from '../../util/ui-event-manager';
import { ViewController } from '../nav/view-controller';
import { ViewController } from '../../navigation/view-controller';
/**
@ -21,16 +19,21 @@ import { ViewController } from '../nav/view-controller';
*/
@Component({
selector: '.picker-col',
template: `
<div *ngIf="col.prefix" class="picker-prefix" [style.width]="col.prefixWidth">{{col.prefix}}</div>
<div class="picker-opts" #colEle [style.width]="col.optionsWidth">
<button ion-button="picker-opt" *ngFor="let o of col.options; let i=index" [style.transform]="o._trans" [style.transitionDuration]="o._dur" [style.webkitTransform]="o._trans" [style.webkitTransitionDuration]="o._dur" [class.picker-opt-selected]="col.selectedIndex === i" [class.picker-opt-disabled]="o.disabled" (click)="optClick($event, i)" type="button">
{{o.text}}
</button>
</div>
<div *ngIf="col.suffix" class="picker-suffix" [style.width]="col.suffixWidth">{{col.suffix}}</div>
`,
directives: [NgFor, NgIf],
template:
'<div *ngIf="col.prefix" class="picker-prefix" [style.width]="col.prefixWidth">{{col.prefix}}</div>' +
'<div class="picker-opts" #colEle [style.width]="col.optionsWidth">' +
'<button *ngFor="let o of col.options; let i=index" [style.transform]="o._trans" ' +
'[style.transitionDuration]="o._dur" ' +
'[style.webkitTransform]="o._trans" ' +
'[style.webkitTransitionDuration]="o._dur" ' +
'[class.picker-opt-selected]="col.selectedIndex === i" [class.picker-opt-disabled]="o.disabled" ' +
'(click)="optClick($event, i)" ' +
'type="button" ' +
'ion-button="picker-opt">' +
'{{o.text}}' +
'</button>' +
'</div>' +
'<div *ngIf="col.suffix" class="picker-suffix" [style.width]="col.suffixWidth">{{col.suffix}}</div>',
host: {
'[style.min-width]': 'col.columnWidth',
'[class.picker-opts-left]': 'col.align=="left"',
@ -57,7 +60,7 @@ export class PickerColumnCmp {
@Output() ionChange: EventEmitter<any> = new EventEmitter();
constructor(config: Config, private elementRef: ElementRef, private _sanitizer: DomSanitizationService) {
constructor(config: Config, private elementRef: ElementRef, private _sanitizer: DomSanitizer) {
this.rotateFactor = config.getNumber('pickerRotateFactor', 0);
}
@ -344,7 +347,6 @@ export class PickerColumnCmp {
}
/**
* @private
*/
@ -367,18 +369,18 @@ export class PickerColumnCmp {
</div>
</div>
`,
directives: [Backdrop, NgClass, NgFor, PickerColumnCmp],
host: {
'role': 'dialog'
},
encapsulation: ViewEncapsulation.None,
})
export class PickerCmp {
@ViewChildren(PickerColumnCmp) private _cols: QueryList<PickerColumnCmp>;
private d: PickerOptions;
private enabled: boolean;
private lastClick: number;
private id: number;
@ViewChildren(PickerColumnCmp) _cols: QueryList<PickerColumnCmp>;
d: PickerOptions;
enabled: boolean;
lastClick: number;
id: number;
mode: string;
constructor(
private _viewCtrl: ViewController,
@ -388,6 +390,8 @@ export class PickerCmp {
renderer: Renderer
) {
this.d = params.data;
this.mode = _config.get('mode');
renderer.setElementClass(_elementRef.nativeElement, `picker-${this.mode}`, true);
if (this.d.cssClass) {
this.d.cssClass.split(' ').forEach(cssClass => {
@ -399,7 +403,7 @@ export class PickerCmp {
this.lastClick = 0;
}
ionViewLoaded() {
ionViewDidLoad() {
// normalize the data
let data = this.d;
@ -452,14 +456,14 @@ export class PickerCmp {
});
}
private _colChange(selectedOption: PickerColumnOption) {
_colChange(selectedOption: PickerColumnOption) {
// one of the columns has changed its selected index
var picker = <Picker>this._viewCtrl;
picker.ionChange.emit(this.getSelected());
}
@HostListener('body:keyup', ['$event'])
private _keyUp(ev: KeyboardEvent) {
_keyUp(ev: KeyboardEvent) {
if (this.enabled && this._viewCtrl.isLast()) {
if (ev.keyCode === Key.ENTER) {
if (this.lastClick + 1000 < Date.now()) {
@ -547,10 +551,8 @@ export class PickerCmp {
* Animations for pickers
*/
class PickerSlideIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
init() {
let ele = this.enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.picker-wrapper'));
@ -564,10 +566,8 @@ Transition.register('picker-slide-in', PickerSlideIn);
class PickerSlideOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
init() {
let ele = this.leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.picker-wrapper'));

View File

@ -2,10 +2,10 @@ import { EventEmitter, Injectable, Output } from '@angular/core';
import { App } from '../app/app';
import { isPresent } from '../../util/util';
import { NavOptions } from '../nav/nav-interfaces';
import { NavOptions } from '../../navigation/nav-util';
import { PickerCmp } from './picker-component';
import { PickerOptions, PickerColumn } from './picker-options';
import { ViewController } from '../nav/view-controller';
import { ViewController } from '../../navigation/view-controller';
/**
* @private
@ -20,16 +20,11 @@ export class Picker extends ViewController {
opts.buttons = opts.buttons || [];
opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
super(PickerCmp, opts);
super(PickerCmp, opts, null);
this._app = app;
this.isOverlay = true;
this.ionChange = new EventEmitter<any>();
// by default, pickers should not fire lifecycle events of other views
// for example, when an picker enters, the current active view should
// not fire its lifecycle events because it's not conceptually leaving
this.fireOtherLifecycles = false;
}
/**
@ -59,7 +54,7 @@ export class Picker extends ViewController {
}
refresh() {
this.instance.refresh && this.instance.refresh();
this._cmp && this._cmp.instance.refresh && this._cmp.instance.refresh();
}
/**
@ -83,7 +78,7 @@ export class Picker extends ViewController {
* @private
* DEPRECATED: Please inject PickerController instead
*/
private static create(opt: any) {
static create(opt: any) {
// deprecated warning: added beta.11 2016-06-27
console.warn('Picker.create(..) has been deprecated. Please inject PickerController instead');
}

View File

@ -1,16 +1,13 @@
import { Component, ComponentResolver, ElementRef, HostListener, Renderer, ViewChild, ViewContainerRef } from '@angular/core';
import { Component, ComponentFactoryResolver, ElementRef, HostListener, Renderer, ViewChild, ViewContainerRef } from '@angular/core';
import { addSelector } from '../../config/bootstrap';
import { Animation } from '../../animations/animation';
import { Backdrop } from '../backdrop/backdrop';
import { Config } from '../../config/config';
import { CSS, nativeRaf } from '../../util/dom';
import { isPresent, pascalCaseToDashCase } from '../../util/util';
import { pascalCaseToDashCase } from '../../util/util';
import { Key } from '../../util/key';
import { NavParams } from '../nav/nav-params';
import { NavParams } from '../../navigation/nav-params';
import { PageTransition } from '../../transitions/page-transition';
import { TransitionOptions } from '../../transitions/transition';
import { ViewController } from '../nav/view-controller';
import { ViewController } from '../../navigation/view-controller';
/**
@ -18,41 +15,45 @@ import { ViewController } from '../nav/view-controller';
*/
@Component({
selector: 'ion-popover',
template: `
<ion-backdrop (click)="bdClick($event)" [class.hide-backdrop]="!d.showBackdrop"></ion-backdrop>
<div class="popover-wrapper">
<div class="popover-arrow"></div>
<div class="popover-content">
<div class="popover-viewport">
<div #viewport nav-viewport></div>
</div>
</div>
</div>
`,
directives: [Backdrop]
template:
'<ion-backdrop (click)="_bdClick()" [class.hide-backdrop]="!d.showBackdrop"></ion-backdrop>' +
'<div class="popover-wrapper">' +
'<div class="popover-arrow"></div>' +
'<div class="popover-content">' +
'<div class="popover-viewport">' +
'<div #viewport nav-viewport></div>' +
'</div>' +
'</div>' +
'</div>'
})
export class PopoverCmp {
@ViewChild('viewport', {read: ViewContainerRef}) viewport: ViewContainerRef;
private d: {
@ViewChild('viewport', {read: ViewContainerRef}) _viewport: ViewContainerRef;
d: {
cssClass?: string;
showBackdrop?: boolean;
enableBackdropDismiss?: boolean;
};
private enabled: boolean;
private id: number;
private showSpinner: boolean;
/** @private */
_enabled: boolean;
/** @private */
id: number;
constructor(
private _compiler: ComponentResolver,
private _elementRef: ElementRef,
private _renderer: Renderer,
private _config: Config,
private _navParams: NavParams,
private _viewCtrl: ViewController
public _cfr: ComponentFactoryResolver,
public _elementRef: ElementRef,
public _renderer: Renderer,
public _config: Config,
public _navParams: NavParams,
public _viewCtrl: ViewController
) {
this.d = _navParams.data.opts;
_renderer.setElementClass(_elementRef.nativeElement, `popover-${_config.get('mode')}`, true);
if (this.d.cssClass) {
this.d.cssClass.split(' ').forEach(cssClass => {
// Make sure the class isn't whitespace, otherwise it throws exceptions
@ -63,46 +64,43 @@ export class PopoverCmp {
this.id = (++popoverIds);
}
ionViewWillEnter() {
addSelector(this._navParams.data.componentType, 'ion-popover-inner');
this._compiler.resolveComponent(this._navParams.data.componentType).then((componentFactory) => {
let componentRef = this.viewport.createComponent(componentFactory, this.viewport.length, this.viewport.parentInjector);
this._viewCtrl.setInstance(componentRef.instance);
// manually fire ionViewWillEnter() since PopoverCmp's ionViewWillEnter already happened
this._viewCtrl.fireWillEnter();
});
}
ngAfterViewInit() {
let activeElement: any = document.activeElement;
if (document.activeElement) {
activeElement.blur();
}
this.enabled = true;
this._load(this._navParams.data.component);
}
dismiss(role: any): Promise<any> {
return this._viewCtrl.dismiss(null, role);
/** @private */
_load(component: any) {
if (component) {
const componentFactory = this._cfr.resolveComponentFactory(component);
// ******** DOM WRITE ****************
const componentRef = this._viewport.createComponent(componentFactory, this._viewport.length, this._viewport.parentInjector, []);
this._viewCtrl._setInstance(componentRef.instance);
this._setCssClass(componentRef, pascalCaseToDashCase(component.name));
this._enabled = true;
}
}
bdTouch(ev: UIEvent) {
ev.preventDefault();
ev.stopPropagation();
/** @private */
_setCssClass(componentRef: any, className: string) {
this._renderer.setElementClass(componentRef.location.nativeElement, className, true);
}
bdClick() {
if (this.enabled && this.d.enableBackdropDismiss) {
this.dismiss('backdrop');
_bdClick() {
if (this._enabled && this.d.enableBackdropDismiss) {
return this._viewCtrl.dismiss(null, 'backdrop');
}
}
@HostListener('body:keyup', ['$event'])
private _keyUp(ev: KeyboardEvent) {
if (this.enabled && ev.keyCode === Key.ESCAPE && this._viewCtrl.isLast()) {
this.bdClick();
_keyUp(ev: KeyboardEvent) {
if (this._enabled && ev.keyCode === Key.ESCAPE && this._viewCtrl.isLast()) {
this._bdClick();
}
}
}
@ -112,9 +110,6 @@ export class PopoverCmp {
* Animations for popover
*/
class PopoverTransition extends PageTransition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(enteringView, leavingView, opts);
}
mdPositionView(nativeEle: HTMLElement, ev: any) {
let originY = 'top';
@ -138,7 +133,6 @@ class PopoverTransition extends PageTransition {
let targetTop = (targetDim && 'top' in targetDim) ? targetDim.top : (bodyHeight / 2) - (popoverHeight / 2);
let targetLeft = (targetDim && 'left' in targetDim) ? targetDim.left : (bodyWidth / 2) - (popoverWidth / 2);
let targetWidth = targetDim && targetDim.width || 0;
let targetHeight = targetDim && targetDim.height || 0;
let popoverCSS = {
@ -170,7 +164,7 @@ class PopoverTransition extends PageTransition {
popoverEle.style.top = popoverCSS.top + 'px';
popoverEle.style.left = popoverCSS.left + 'px';
popoverEle.style[CSS.transformOrigin] = originY + ' ' + originX;
(<any>popoverEle.style)[CSS.transformOrigin] = originY + ' ' + originX;
// Since the transition starts before styling is done we
// want to wait for the styles to apply before showing the wrapper
@ -250,7 +244,7 @@ class PopoverTransition extends PageTransition {
popoverEle.style.top = popoverCSS.top + 'px';
popoverEle.style.left = popoverCSS.left + 'px';
popoverEle.style[CSS.transformOrigin] = originY + ' ' + originX;
(<any>popoverEle.style)[CSS.transformOrigin] = originY + ' ' + originX;
// Since the transition starts before styling is done we
// want to wait for the styles to apply before showing the wrapper
@ -259,10 +253,8 @@ class PopoverTransition extends PageTransition {
}
class PopoverPopIn extends PopoverTransition {
constructor(enteringView: ViewController, leavingView: ViewController, private opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
init() {
let ele = this.enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));
@ -288,10 +280,8 @@ PageTransition.register('popover-pop-in', PopoverPopIn);
class PopoverPopOut extends PopoverTransition {
constructor(enteringView: ViewController, leavingView: ViewController, private opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
init() {
let ele = this.leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));
@ -309,11 +299,8 @@ PageTransition.register('popover-pop-out', PopoverPopOut);
class PopoverMdPopIn extends PopoverTransition {
constructor(enteringView: ViewController, leavingView: ViewController, private opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
init() {
let ele = this.enteringView.pageRef().nativeElement;
let content = new Animation(ele.querySelector('.popover-content'));
let viewport = new Animation(ele.querySelector('.popover-viewport'));
@ -338,10 +325,8 @@ PageTransition.register('popover-md-pop-in', PopoverMdPopIn);
class PopoverMdPopOut extends PopoverTransition {
constructor(enteringView: ViewController, leavingView: ViewController, private opts: TransitionOptions) {
super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
init() {
let ele = this.leavingView.pageRef().nativeElement;
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));
wrapper.fromTo('opacity', 0.99, 0);

View File

@ -2,10 +2,10 @@ import { Injectable } from '@angular/core';
import { App } from '../app/app';
import { isPresent } from '../../util/util';
import { NavOptions } from '../nav/nav-interfaces';
import { NavOptions } from '../../navigation/nav-util';
import { PopoverCmp } from './popover-component';
import { PopoverOptions } from './popover-options';
import { ViewController } from '../nav/view-controller';
import { ViewController } from '../../navigation/view-controller';
/**
@ -14,20 +14,15 @@ import { ViewController } from '../nav/view-controller';
export class Popover extends ViewController {
private _app: App;
constructor(app: App, componentType: any, data: any = {}, opts: PopoverOptions = {}) {
constructor(app: App, component: any, data: any = {}, opts: PopoverOptions = {}) {
opts.showBackdrop = isPresent(opts.showBackdrop) ? !!opts.showBackdrop : true;
opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
data.componentType = componentType;
data.component = component;
data.opts = opts;
super(PopoverCmp, data);
super(PopoverCmp, data, null);
this._app = app;
this.isOverlay = true;
// by default, popovers should not fire lifecycle events of other views
// for example, when a popover enters, the current active view should
// not fire its lifecycle events because it's not conceptually leaving
this.fireOtherLifecycles = false;
}
/**
@ -52,7 +47,7 @@ export class Popover extends ViewController {
* @private
* DEPRECATED: Please inject PopoverController instead
*/
static create(componentType: any, data = {}, opts: PopoverOptions = {}) {
static create(component: any, data = {}, opts: PopoverOptions = {}) {
// deprecated warning: added beta.11 2016-06-27
console.warn('Popover.create(..) has been deprecated. Please inject PopoverController instead');
}
@ -110,7 +105,7 @@ export class Popover extends ViewController {
* ```ts
* @Component({})
* class MyPage {
* constructor(private popoverCtrl: PopoverController) {}
* constructor(public popoverCtrl: PopoverController) {}
*
* presentPopover(myEvent) {
* let popover = this.popoverCtrl.create(PopoverPage);
@ -138,7 +133,7 @@ export class Popover extends ViewController {
* `
* })
* class PopoverPage {
* constructor(private viewCtrl: ViewController) {}
* constructor(public viewCtrl: ViewController) {}
*
* close() {
* this.viewCtrl.dismiss();
@ -165,12 +160,12 @@ export class PopoverController {
/**
* Present a popover. See below for options
* @param {object} componentType The Popover
* @param {object} component The Popover
* @param {object} data Any data to pass to the Popover view
* @param {PopoverOptions} opts Popover options
*/
create(componentType: any, data = {}, opts: PopoverOptions = {}): Popover {
return new Popover(this._app, componentType, data, opts);
create(component: any, data = {}, opts: PopoverOptions = {}): Popover {
return new Popover(this._app, component, data, opts);
}
}

View File

@ -1,12 +1,15 @@
import { AfterContentInit, ContentChild, Directive, ElementRef, EventEmitter, forwardRef, Input, Output, Provider, Renderer } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { ContentChild, Directive, ElementRef, EventEmitter, forwardRef, Output, Renderer } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ListHeader } from '../list/list';
import { ListHeader } from '../list/list-header';
import { isCheckedProperty } from '../../util/util';
import { RadioButton } from './radio-button';
export const RADIO_VALUE_ACCESSOR = new Provider(
NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => RadioGroup), multi: true});
export const RADIO_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RadioGroup),
multi: true
};
/**
* @name RadioGroup
@ -62,16 +65,31 @@ export const RADIO_VALUE_ACCESSOR = new Provider(
@Directive({
selector: '[radio-group]',
host: {
'[attr.aria-activedescendant]': 'activeId',
'role': 'radiogroup'
},
providers: [RADIO_VALUE_ACCESSOR]
})
export class RadioGroup implements AfterContentInit, ControlValueAccessor {
private _btns: Array<RadioButton> = [];
private _fn: Function;
private _ids: number = -1;
private _init: boolean = false;
export class RadioGroup {
/**
* @private
*/
_btns: RadioButton[] = [];
/**
* @private
*/
_fn: Function;
/**
* @private
*/
_ids: number = -1;
/**
* @private
*/
_init: boolean = false;
/**
* @private
@ -145,7 +163,7 @@ export class RadioGroup implements AfterContentInit, ControlValueAccessor {
/**
* @private
*/
private _update() {
_update() {
// loop through each of the radiobuttons
let hasChecked = false;
this._btns.forEach(radioButton => {
@ -163,7 +181,10 @@ export class RadioGroup implements AfterContentInit, ControlValueAccessor {
});
}
private _setActive(radioButton: RadioButton) {
/**
* @private
*/
_setActive(radioButton: RadioButton) {
this._renderer.setElementAttribute(this._elementRef.nativeElement, 'aria-activedescendant', radioButton.id);
}
@ -199,7 +220,7 @@ export class RadioGroup implements AfterContentInit, ControlValueAccessor {
* @private
*/
@ContentChild(ListHeader)
private set _header(header: any) {
set _header(header: any) {
if (header) {
if (!header.id) {
header.id = 'rg-hdr-' + this.id;

View File

@ -1,10 +1,7 @@
import { Component, Input, ViewEncapsulation } from '@angular/core';
import { NgIf } from '@angular/common';
import { Config } from '../../config/config';
import { Icon } from '../icon/icon';
import { Refresher } from './refresher';
import { Spinner } from '../spinner/spinner';
/**
@ -12,21 +9,19 @@ import { Spinner } from '../spinner/spinner';
*/
@Component({
selector: 'ion-refresher-content',
template: `
<div class="refresher-pulling">
<div class="refresher-pulling-icon" *ngIf="pullingIcon">
<ion-icon [name]="pullingIcon"></ion-icon>
</div>
<div class="refresher-pulling-text" [innerHTML]="pullingText" *ngIf="pullingText"></div>
</div>
<div class="refresher-refreshing">
<div class="refresher-refreshing-icon">
<ion-spinner [name]="refreshingSpinner"></ion-spinner>
</div>
<div class="refresher-refreshing-text" [innerHTML]="refreshingText" *ngIf="refreshingText"></div>
</div>
`,
directives: [Icon, NgIf, Spinner],
template:
'<div class="refresher-pulling">' +
'<div class="refresher-pulling-icon" *ngIf="pullingIcon">' +
'<ion-icon [name]="pullingIcon"></ion-icon>' +
'</div>' +
'<div class="refresher-pulling-text" [innerHTML]="pullingText" *ngIf="pullingText"></div>' +
'</div>' +
'<div class="refresher-refreshing">' +
'<div class="refresher-refreshing-icon">' +
'<ion-spinner [name]="refreshingSpinner"></ion-spinner>' +
'</div>' +
'<div class="refresher-refreshing-text" [innerHTML]="refreshingText" *ngIf="refreshingText"></div>' +
'</div>',
host: {
'[attr.state]': 'r.state'
},
@ -55,7 +50,7 @@ export class RefresherContent {
@Input() refreshingText: string;
constructor(private r: Refresher, private _config: Config) {}
constructor(public r: Refresher, private _config: Config) {}
/**
* @private

View File

@ -95,14 +95,14 @@ import { PointerEvents, UIEventManager } from '../../util/ui-event-manager';
}
})
export class Refresher {
private _appliedStyles: boolean = false;
private _didStart: boolean;
private _lastCheck: number = 0;
private _isEnabled: boolean = true;
private _gesture: GestureDelegate;
private _events: UIEventManager = new UIEventManager(false);
private _pointerEvents: PointerEvents;
private _top: string = '';
_appliedStyles: boolean = false;
_didStart: boolean;
_lastCheck: number = 0;
_isEnabled: boolean = true;
_gesture: GestureDelegate;
_events: UIEventManager = new UIEventManager(false);
_pointerEvents: PointerEvents;
_top: string = '';
/**
* The current state which the refresher is in. The refresher's states include:
@ -199,13 +199,13 @@ export class Refresher {
constructor(@Host() private _content: Content, private _zone: NgZone, gestureCtrl: GestureController) {
_content.addCssClass('has-refresher');
_content.setElementClass('has-refresher', true);
this._gesture = gestureCtrl.create('refresher', {
priority: GesturePriority.Refresher,
});
}
private _onStart(ev: TouchEvent): any {
_onStart(ev: TouchEvent): any {
// if multitouch then get out immediately
if (ev.touches && ev.touches.length > 1) {
return false;
@ -241,7 +241,7 @@ export class Refresher {
return true;
}
private _onMove(ev: TouchEvent) {
_onMove(ev: TouchEvent) {
// this method can get called like a bazillion times per second,
// so it's built to be as efficient as possible, and does its
// best to do any DOM read/writes only when absolutely necessary
@ -340,7 +340,7 @@ export class Refresher {
});
}
private _onMoveInZone() {
_onMoveInZone() {
// set pull progress
this.progress = (this.deltaY / this.pullMin);
@ -374,7 +374,7 @@ export class Refresher {
return 4;
}
private _onEnd(ev: UIEvent) {
_onEnd() {
// only run in a zone when absolutely necessary
if (this.state === STATE_READY) {
@ -397,7 +397,7 @@ export class Refresher {
this.startY = null;
}
private _beginRefresh() {
_beginRefresh() {
// assumes we're already back in a zone
// they pulled down far enough, so it's ready to refresh
this.state = STATE_REFRESHING;
@ -430,7 +430,7 @@ export class Refresher {
this._close(STATE_CANCELLING, '');
}
private _close(state: string, delay: string) {
_close(state: string, delay: string) {
var timer: number;
function close(ev: any) {
@ -461,7 +461,7 @@ export class Refresher {
}
}
private _setCss(y: number, duration: string, overflowVisible: boolean, delay: string) {
_setCss(y: number, duration: string, overflowVisible: boolean, delay: string) {
this._appliedStyles = (y > 0);
var content = this._content;
@ -471,7 +471,7 @@ export class Refresher {
content.setScrollElementStyle('overflow', (overflowVisible ? 'hidden' : ''));
}
private _setListeners(shouldListen: boolean) {
_setListeners(shouldListen: boolean) {
this._events.unlistenAll();
this._pointerEvents = null;
if (shouldListen) {

View File

@ -1,6 +1,8 @@
import { Refresher, Content, Config, GestureController, Ion } from '../../../../src';
import { Refresher } from '../refresher';
import { Content } from '../../content/content';
import { GestureController } from '../../../gestures/gesture-controller';
import { mockConfig, mockElementRef, mockRenderer, mockZone } from '../../../util/mock-providers';
export function run() {
describe('Refresher', () => {
@ -20,19 +22,19 @@ describe('Refresher', () => {
it('should do nothing if state=cancelling', () => {
refresher.state = 'cancelling';
var results = refresher._onEnd();
refresher._onEnd();
expect(refresher.state).toEqual('cancelling');
});
it('should do nothing if state=completing', () => {
refresher.state = 'completing';
var results = refresher._onEnd();
refresher._onEnd();
expect(refresher.state).toEqual('completing');
});
it('should do nothing if state=refreshing', () => {
refresher.state = 'refreshing';
var results = refresher._onEnd();
refresher._onEnd();
expect(refresher.state).toEqual('refreshing');
});
@ -93,7 +95,7 @@ describe('Refresher', () => {
setContentScrollTop(0);
refresher.startY = 100;
refresher.pullMin = 80;
let result = refresher._onMove( touchEv(125) );
refresher._onMove( <TouchEvent> <any> touchEv(125) );
expect(getScrollElementStyles().transform).toEqual('translateY(25px) translateZ(0px)');
expect(getScrollElementStyles().transitionDuration).toEqual('0ms');
@ -106,7 +108,7 @@ describe('Refresher', () => {
setContentScrollTop(1);
refresher.startY = 100;
let result = refresher._onMove( touchEv(95) );
let result = refresher._onMove( <TouchEvent> <any> touchEv(95) );
expect(result).toEqual(6);
});
@ -116,7 +118,7 @@ describe('Refresher', () => {
setContentScrollTop(50);
refresher.startY = 100;
let result = refresher._onMove( touchEv(125) );
let result = refresher._onMove( <TouchEvent> <any> touchEv(125) );
expect(refresher.state).toEqual('inactive');
expect(refresher.progress).toEqual(0);
@ -128,7 +130,7 @@ describe('Refresher', () => {
refresher._appliedStyles = true;
refresher.startY = 100;
let result = refresher._onMove( touchEv(85) );
let result = refresher._onMove( <TouchEvent> <any> touchEv(85) );
expect(refresher.state).toEqual('inactive');
expect(getScrollElementStyles().transform).toEqual('translateZ(0px)');
@ -141,72 +143,71 @@ describe('Refresher', () => {
setContentScrollTop(50);
refresher.startY = 100;
var results = refresher._onMove(touchEv(80));
var results = refresher._onMove(<TouchEvent> <any> touchEv(80));
expect(results).toEqual(6);
});
it('should not run when scrolling up, but isnt actively dragging', () => {
setContentScrollTop(1);
refresher.startY = 100;
refresher._isDragging = false
var results = refresher._onMove(touchEv(85));
var results = refresher._onMove(<TouchEvent> <any> touchEv(85));
expect(results).toEqual(6);
});
it('should set the deltaY', () => {
setContentScrollTop(1);
refresher.startY = 100;
refresher._onMove( touchEv(133) );
refresher._onMove( <TouchEvent> <any> touchEv(133) );
expect(refresher.deltaY).toEqual(33);
refresher._lastCheck = 0; // force allow next check
refresher.startY = 100;
var results = refresher._onMove( touchEv(50) );
var results = refresher._onMove( <TouchEvent> <any> touchEv(50) );
expect(results).toEqual(6);
expect(refresher.deltaY).toEqual(-50);
});
it('should not run if it already ran less than 16ms ago', () => {
refresher.startY = 100;
var results = refresher._onMove(touchEv(88));
var results = refresher._onMove(<TouchEvent> <any> touchEv(88));
expect(results).toEqual(6);
results = refresher._onMove(touchEv(88));
results = refresher._onMove(<TouchEvent> <any> touchEv(88));
expect(results).toEqual(3);
});
it('should not run if state=refreshing', () => {
refresher.startY = 100;
refresher.state = 'refreshing';
var results = refresher._onMove( touchEv(88) );
var results = refresher._onMove( <TouchEvent> <any> touchEv(88) );
expect(results).toEqual(2);
});
it('should not run if state=completing', () => {
refresher.startY = 100;
refresher.state = 'completing';
var results = refresher._onMove( touchEv(88) );
var results = refresher._onMove( <TouchEvent> <any> touchEv(88) );
expect(results).toEqual(2);
});
it('should not run if state=cancelling', () => {
refresher.startY = 100;
refresher.state = 'cancelling';
var results = refresher._onMove( touchEv(88) );
var results = refresher._onMove( <TouchEvent> <any> touchEv(88) );
expect(results).toEqual(2);
});
it('should not run if no startY', () => {
refresher.startY = null;
var results = refresher._onMove( touchEv(88) );
var results = refresher._onMove( <TouchEvent> <any> touchEv(88) );
expect(results).toEqual(2);
});
it('should not run if multiple touches', () => {
var results = refresher._onMove({
touches: [{},{}]
var results = refresher._onMove(<TouchEvent> <any> {
touches: [{}, {}]
});
expect(results).toEqual(1);
});
@ -214,23 +215,18 @@ describe('Refresher', () => {
});
let config = new Config();
let refresher: Refresher;
let content: Content;
let contentElementRef;
let gestureController: GestureController;
let zone = {
run: function (cb) { cb(); },
runOutsideAngular: function (cb) { cb(); }
};
beforeEach(() => {
contentElementRef = mockElementRef();
gestureController = new GestureController();
content = new Content(contentElementRef, config, null, null, zone, null, null);
content._scrollEle = document.createElement('scroll-content');
let gestureController = new GestureController(null);
let elementRef = mockElementRef();
elementRef.nativeElement.children.push('');
content = new Content(mockConfig(), mockElementRef(), mockRenderer(), null, null, mockZone(), null, null);
content._scrollEle = document.createElement('div');
content._scrollEle.className = 'scroll-content';
refresher = new Refresher(content, zone, gestureController);
refresher = new Refresher(content, mockZone(), gestureController);
});
function touchEv(y: number) {
@ -238,24 +234,24 @@ describe('Refresher', () => {
type: 'mockTouch',
touches: [{clientY: y}],
preventDefault: function(){}
}
}
function mockElementRef() {
return {
nativeElement: {
classList: { add: function(){}, remove: function(){} },
scrollTop: 0,
hasAttribute: function(){},
children: {length: 1 }
}
}
};
}
function setContentScrollTop(scrollTop) {
content.getContentDimensions = function() {
return {
scrollTop: scrollTop
scrollTop: scrollTop,
scrollHeight: null,
contentHeight: null,
contentTop: null,
contentBottom: null,
contentWidth: null,
contentLeft: null,
contentRight: null,
scrollBottom: null,
scrollWidth: null,
scrollLeft: null,
scrollRight: null
};
};
}
@ -265,5 +261,3 @@ describe('Refresher', () => {
}
});
}

View File

@ -1,6 +1,6 @@
import { Component, ElementRef, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
import { ChangeDetectionStrategy, Component, ElementRef, Input, ViewEncapsulation } from '@angular/core';
import { Ion } from '../ion';
import { isTrueProperty } from '../../util/util';
/**
* @name Scroll
@ -17,53 +17,85 @@ import { Ion } from '../ion';
* <ion-scroll scrollX="true" scrollY="true">
* </ion-scroll>
* ```
*@property {boolean} [scrollX] - whether to enable scrolling along the X axis
*@property {boolean} [scrollY] - whether to enable scrolling along the Y axis; requires the following CSS declaration: ion-scroll { white-space: nowrap; }
*@property {boolean} [zoom] - whether to enable zooming
*@property {number} [maxZoom] - set the max zoom amount for ion-scroll
* @property {boolean} [scrollX] - whether to enable scrolling along the X axis
* @property {boolean} [scrollY] - whether to enable scrolling along the Y axis; requires the following CSS declaration: ion-scroll { white-space: nowrap; }
* @property {boolean} [zoom] - whether to enable zooming
* @property {number} [maxZoom] - set the max zoom amount for ion-scroll
* @demo /docs/v2/demos/scroll/
*/
@Component({
selector: 'ion-scroll',
inputs: [
'scrollX', 'scrollY', 'zoom', 'maxZoom'
],
template:
'<div class="scroll-content">' +
'<div class="scroll-zoom-wrapper">' +
'<ng-content></ng-content>' +
'</div>' +
'</div>',
host: {
'[class.scroll-x]': 'scrollX',
'[class.scroll-y]': 'scrollY'
},
template:
'<scroll-content>' +
'<div class="scroll-zoom-wrapper">' +
'<ng-content></ng-content>' +
'</div>' +
'</scroll-content>',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class Scroll extends Ion {
/**
* @private
*/
private maxScale: number = 3;
/**
* @private
*/
private zoomDuration: number = 250;
/**
* @private
*/
private scrollElement: HTMLElement;
export class Scroll {
_scrollX: boolean = false;
_scrollY: boolean = false;
_zoom: boolean = false;
_maxZoom: number = 1;
constructor(elementRef: ElementRef) {
super(elementRef);
@Input()
get scrollX() {
return this._scrollX;
}
set scrollX(val: any) {
this._scrollX = isTrueProperty(val);
}
@Input()
get scrollY() {
return this._scrollY;
}
set scrollY(val: any) {
this._scrollY = isTrueProperty(val);
}
@Input()
get zoom() {
return this._zoom;
}
set zoom(val: any) {
this._zoom = isTrueProperty(val);
}
@Input()
get maxZoom() {
return this._maxZoom;
}
set maxZoom(val: any) {
this._maxZoom = val;
}
/**
* @private
*/
maxScale: number = 3;
/**
* @private
*/
zoomDuration: number = 250;
/**
* @private
*/
scrollElement: HTMLElement;
constructor(private _elementRef: ElementRef) {}
/**
* @private
*/
ngOnInit() {
this.scrollElement = this.getNativeElement().children[0];
this.scrollElement = this._elementRef.nativeElement.children[0];
}
/**

View File

@ -1,4 +1,4 @@
it('should navigate to details', function() {
element(by.css('.e2eSearchbarNavItem')).click();
element(by.css('.e2eSearchbarNavItem:first-child')).click();
});

View File

@ -1,19 +1,22 @@
import { AfterContentInit, Component, ContentChildren, ElementRef, EventEmitter, forwardRef, Input, HostListener, OnDestroy, Optional, Output, Provider, Renderer, QueryList, ViewEncapsulation } from '@angular/core';
import { NgIf } from '@angular/common';
import { AfterContentInit, Component, ContentChildren, ElementRef, EventEmitter, forwardRef, Input, HostListener, OnDestroy, Optional, Output, Renderer, QueryList, ViewEncapsulation } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { ActionSheet } from '../action-sheet/action-sheet';
import { Alert } from '../alert/alert';
import { App } from '../app/app';
import { Config } from '../../config/config';
import { Form } from '../../util/form';
import { Ion } from '../ion';
import { isBlank, isCheckedProperty, isTrueProperty, merge } from '../../util/util';
import { Item } from '../item/item';
import { NavController } from '../nav/nav-controller';
import { NavController } from '../../navigation/nav-controller';
import { Option } from '../option/option';
export const SELECT_VALUE_ACCESSOR = new Provider(
NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => Select), multi: true});
export const SELECT_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => Select),
multi: true
};
/**
* @name Select
@ -119,36 +122,35 @@ export const SELECT_VALUE_ACCESSOR = new Provider(
*/
@Component({
selector: 'ion-select',
template: `
<div *ngIf="!_text" class="select-placeholder select-text">{{placeholder}}</div>
<div *ngIf="_text" class="select-text">{{selectedText || _text}}</div>
<div class="select-icon">
<div class="select-icon-inner"></div>
</div>
<button ion-button="item-cover"
aria-haspopup="true"
[id]="id"
[attr.aria-labelledby]="_labelId"
[attr.aria-disabled]="_disabled">
</button>
`,
directives: [NgIf],
template:
'<div *ngIf="!_text" class="select-placeholder select-text">{{placeholder}}</div>' +
'<div *ngIf="_text" class="select-text">{{selectedText || _text}}</div>' +
'<div class="select-icon">' +
'<div class="select-icon-inner"></div>' +
'</div>' +
'<button aria-haspopup="true" ' +
'[id]="id" ' +
'ion-button="item-cover" ' +
'[attr.aria-labelledby]="_labelId" ' +
'[attr.aria-disabled]="_disabled" ' +
'class="item-cover">' +
'</button>',
host: {
'[class.select-disabled]': '_disabled'
},
providers: [SELECT_VALUE_ACCESSOR],
encapsulation: ViewEncapsulation.None,
})
export class Select implements AfterContentInit, ControlValueAccessor, OnDestroy {
private _disabled: any = false;
private _labelId: string;
private _multi: boolean = false;
private _options: QueryList<Option>;
private _values: string[] = [];
private _texts: string[] = [];
private _text: string = '';
private _fn: Function;
private _isOpen: boolean = false;
export class Select extends Ion implements AfterContentInit, ControlValueAccessor, OnDestroy {
_disabled: any = false;
_labelId: string;
_multi: boolean = false;
_options: QueryList<Option>;
_values: string[] = [];
_texts: string[] = [];
_text: string = '';
_fn: Function;
_isOpen: boolean = false;
/**
* @private
@ -188,6 +190,14 @@ export class Select implements AfterContentInit, ControlValueAccessor, OnDestroy
*/
@Input() selectedText: string = '';
/**
* @input {string} The mode to apply to this component.
*/
@Input()
set mode(val: string) {
this._setMode('select', val);
}
/**
* @output {any} Any expression you want to evaluate when the selection has changed.
*/
@ -201,22 +211,27 @@ export class Select implements AfterContentInit, ControlValueAccessor, OnDestroy
constructor(
private _app: App,
private _form: Form,
private _elementRef: ElementRef,
private _renderer: Renderer,
@Optional() private _item: Item,
config: Config,
elementRef: ElementRef,
renderer: Renderer,
@Optional() public _item: Item,
@Optional() private _nav: NavController
) {
this._form.register(this);
super(config, elementRef, renderer);
this.mode = config.get('mode');
_form.register(this);
if (_item) {
this.id = 'sel-' + _item.registerInput('select');
this._labelId = 'lbl-' + _item.id;
this._item.setCssClass('item-select', true);
this._item.setElementClass('item-select', true);
}
}
@HostListener('click', ['$event'])
private _click(ev: UIEvent) {
_click(ev: UIEvent) {
if (ev.detail === 0) {
// do not continue if the click event came from a form submit
return;
@ -227,7 +242,7 @@ export class Select implements AfterContentInit, ControlValueAccessor, OnDestroy
}
@HostListener('keyup.space')
private _keyup() {
_keyup() {
if (!this._isOpen) {
this.open();
}
@ -368,7 +383,7 @@ export class Select implements AfterContentInit, ControlValueAccessor, OnDestroy
* @private
*/
@ContentChildren(Option)
private set options(val: QueryList<Option>) {
set options(val: QueryList<Option>) {
this._options = val;
if (!this._values.length) {
@ -383,7 +398,7 @@ export class Select implements AfterContentInit, ControlValueAccessor, OnDestroy
/**
* @private
*/
private _updOpts() {
_updOpts() {
this._texts = [];
if (this._options) {
@ -412,7 +427,7 @@ export class Select implements AfterContentInit, ControlValueAccessor, OnDestroy
set disabled(val) {
this._disabled = isTrueProperty(val);
this._item && this._item.setCssClass('item-select-disabled', this._disabled);
this._item && this._item.setElementClass('item-select-disabled', this._disabled);
}
/**

View File

@ -7,11 +7,10 @@ import { Platform } from '../../platform/platform';
* @private
*/
export class DisplayWhen {
protected isMatch: boolean = false;
private platform: Platform;
private conditions: string[];
isMatch: boolean = false;
conditions: string[];
constructor(conditions: string, platform: Platform, ngZone: NgZone) {
constructor(conditions: string, public platform: Platform, public zone: NgZone) {
this.platform = platform;
if (!conditions) return;
@ -27,10 +26,10 @@ export class DisplayWhen {
}
}
if ( this.orientation() ) {
if (this.orientation()) {
// add window resize listener
platform.onResize(() => {
ngZone.run(() => {
zone.run(() => {
this.orientation();
});
});
@ -108,9 +107,9 @@ export class ShowWhen extends DisplayWhen {
constructor(
@Attribute('showWhen') showWhen: string,
platform: Platform,
ngZone: NgZone
zone: NgZone
) {
super(showWhen, platform, ngZone);
super(showWhen, platform, zone);
}
}
@ -167,9 +166,9 @@ export class HideWhen extends DisplayWhen {
constructor(
@Attribute('hideWhen') hideWhen: string,
platform: Platform,
ngZone: NgZone
zone: NgZone
) {
super(hideWhen, platform, ngZone);
super(hideWhen, platform, zone);
}
}

View File

@ -1,4 +1,4 @@
import { Directive, ElementRef, EventEmitter, HostListener, Input, Output } from '@angular/core';
import { Directive, ElementRef, EventEmitter, HostListener, Input, OnInit, Output, Renderer } from '@angular/core';
import { Config } from '../../config/config';
import { Ion } from '../ion';
@ -21,21 +21,22 @@ import { Tab } from './tab';
'[class.disable-hover]': 'disHover'
}
})
export class TabButton extends Ion {
private disHover: boolean;
private hasTitle: boolean;
private hasIcon: boolean;
private hasTitleOnly: boolean;
private hasIconOnly: boolean;
private hasBadge: boolean;
private layout: string;
export class TabButton extends Ion implements OnInit {
disHover: boolean;
hasTitle: boolean;
hasIcon: boolean;
hasTitleOnly: boolean;
hasIconOnly: boolean;
hasBadge: boolean;
layout: string;
@Input() tab: Tab;
@Output() ionSelect: EventEmitter<Tab> = new EventEmitter<Tab>();
constructor(config: Config, elementRef: ElementRef) {
super(elementRef);
constructor(config: Config, elementRef: ElementRef, renderer: Renderer) {
super(config, elementRef, renderer);
this.disHover = (config.get('hoverCSS') === false);
this.layout = config.get('tabsLayout');
@ -56,9 +57,14 @@ export class TabButton extends Ion {
this.hasBadge = !!this.tab.tabBadge;
}
@HostListener('click', ['$event'])
private onClick(ev: UIEvent) {
@HostListener('click')
onClick(): boolean {
this.ionSelect.emit(this.tab);
ev.preventDefault();
return false;
}
updateHref(href: string) {
this.setElementAttribute('href', href);
}
}

View File

@ -7,7 +7,7 @@ import { Tab } from './tab';
* @private
*/
@Directive({
selector: 'tab-highlight'
selector: '.tab-highlight'
})
export class TabHighlight {
private _init: boolean;
@ -29,4 +29,4 @@ export class TabHighlight {
});
}
}
}

View File

@ -1,6 +1,6 @@
import { App } from '../app/app';
import { Config } from '../../config/config';
import { Coordinates, nativeTimeout, rafFrames } from '../../util/dom';
import { PointerCoordinates, nativeTimeout, rafFrames } from '../../util/dom';
export class Activator {
@ -12,7 +12,7 @@ export class Activator {
this._css = config.get('activatedClass') || 'activated';
}
downAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: Coordinates) {
downAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
// the user just pressed down
let self = this;
if (self.disableActivated(ev)) {
@ -35,7 +35,7 @@ export class Activator {
});
}
upAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: Coordinates) {
upAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
// the user was pressing down, then just let up
rafFrames(CLEAR_STATE_DEFERS, () => {
this.clearState();

View File

@ -1,6 +1,6 @@
import { Activator } from './activator';
import { App } from '../app/app';
import { Coordinates, CSS, hasPointerMoved, nativeRaf, pointerCoord, rafFrames } from '../../util/dom';
import { PointerCoordinates, CSS, hasPointerMoved, nativeRaf, pointerCoord, rafFrames } from '../../util/dom';
import { Config } from '../../config/config';
@ -13,7 +13,7 @@ export class RippleActivator extends Activator {
super(app, config);
}
downAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: Coordinates) {
downAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
let self = this;
if (self.disableActivated(ev)) {
return;
@ -34,7 +34,7 @@ export class RippleActivator extends Activator {
var j = queuedEle.childElementCount;
while (j--) {
var rippleEle: any = queuedEle.children[j];
if (rippleEle.tagName === 'ION-BUTTON-EFFECT') {
if (rippleEle.classList.contains('button-effect')) {
// DOM WRITE
rippleEle.style.left = '-9999px';
rippleEle.style.opacity = '';
@ -56,15 +56,13 @@ export class RippleActivator extends Activator {
});
}
upAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: Coordinates) {
let self = this;
upAction(ev: UIEvent, activatableEle: HTMLElement, startCoord: PointerCoordinates) {
if (!hasPointerMoved(6, startCoord, pointerCoord(ev))) {
let i = activatableEle.childElementCount;
while (i--) {
var rippleEle: any = activatableEle.children[i];
if (rippleEle.tagName === 'ION-BUTTON-EFFECT') {
if (rippleEle.classList.contains('button-effect')) {
var clientPointerX = (startCoord.x - rippleEle.$left);
var clientPointerY = (startCoord.y - rippleEle.$top);

View File

@ -1,4 +1,4 @@
import { Injectable, NgZone } from '@angular/core';
import { Injectable, NgZone, APP_INITIALIZER } from '@angular/core';
import { Activator } from './activator';
import { App } from '../app/app';
@ -224,3 +224,22 @@ const ACTIVATABLE_ATTRIBUTES = /tappable|button/i;
const POINTER_TOLERANCE = 4;
const POINTER_MOVE_UNTIL_CANCEL = 10;
const DISABLE_NATIVE_CLICK_AMOUNT = 2500;
export function setupTapClick(config: Config, app: App, zone: NgZone) {
return function() {
return new TapClick(config, app, zone);
};
}
export function provideTapClick() {
return {
provide: APP_INITIALIZER,
useFactory: setupTapClick,
deps: [
Config,
App,
NgZone
],
multi: true
};
}

View File

@ -0,0 +1,13 @@
import { Directive } from '@angular/core';
/**
* @name Thumbnail
* @module ionic
* @description
*/
@Directive({
selector: 'ion-thumbnail'
})
export class Thumbnail {
}

View File

@ -1,11 +1,12 @@
import { Injectable } from '@angular/core';
import { App } from '../app/app';
import { AppPortal } from '../app/app-root';
import { isPresent } from '../../util/util';
import { NavOptions } from '../nav/nav-interfaces';
import { NavOptions } from '../../navigation/nav-util';
import { ToastOptions } from './toast-options';
import { ToastCmp } from './toast-component';
import { ViewController } from '../nav/view-controller';
import { ViewController } from '../../navigation/view-controller';
/**
* @private
@ -15,7 +16,7 @@ export class Toast extends ViewController {
constructor(app: App, opts: ToastOptions = {}) {
opts.dismissOnPageChange = isPresent(opts.dismissOnPageChange) ? !!opts.dismissOnPageChange : false;
super(ToastCmp, opts);
super(ToastCmp, opts, null);
this._app = app;
// set the position to the bottom if not provided
@ -24,14 +25,8 @@ export class Toast extends ViewController {
}
this.isOverlay = true;
// by default, toasts should not fire lifecycle events of other views
// for example, when an toast enters, the current active view should
// not fire its lifecycle events because it's not conceptually leaving
this.fireOtherLifecycles = false;
}
/**
* @private
*/
@ -61,14 +56,21 @@ export class Toast extends ViewController {
* @returns {Promise} Returns a promise which is resolved when the transition has completed.
*/
present(navOptions: NavOptions = {}) {
return this._app.present(this, navOptions);
return this._app.present(this, navOptions, AppPortal.TOAST);
}
/**
* Dismiss all toast components which have been presented.
*/
dismissAll() {
this._nav && this._nav.popAll();
}
/**
* @private
* DEPRECATED: Please inject ToastController instead
*/
private static create(opt: any) {
static create(opt: any) {
// deprecated warning: added beta.11 2016-06-27
console.warn('Toast.create(..) has been deprecated. Please inject ToastController instead');
}

View File

@ -1,5 +1,8 @@
import { Directive, ElementRef, Input, Renderer } from '@angular/core';
import { Config } from '../../config/config';
import { Ion } from '../ion';
/**
* @private
@ -8,42 +11,28 @@ import { Directive, ElementRef, Input, Renderer } from '@angular/core';
@Directive({
selector: 'h1[color], h2[color], h3[color], h4[color], h5[color], h6[color], a[color], p[color], span[color], b[color], i[color], strong[color], em[color], small[color], sub[color], sup[color]'
})
export class Typography {
/** @internal */
_color: string;
export class Typography extends Ion {
/**
* @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`.
*/
@Input()
get color(): string {
return this._color;
}
set color(value: string) {
this._updateColor(value);
}
constructor(
private _elementRef: ElementRef,
private _renderer: Renderer
) { }
/**
* @internal
*/
_updateColor(newColor: string) {
this._setElementColor(this._color, false);
this._setElementColor(newColor, true);
this._color = newColor;
set color(val: string) {
this._setColor('text', val);
}
/**
* @internal
* @input {string} The mode to apply to this component.
*/
_setElementColor(color: string, isAdd: boolean) {
if (color !== null && color !== '') {
this._renderer.setElementClass(this._elementRef.nativeElement, `text-${color}`, isAdd);
}
@Input()
set mode(val: string) {
this._setMode('text', val);
}
constructor(config: Config, elementRef: ElementRef, renderer: Renderer) {
super(config, elementRef, renderer);
this.mode = config.get('mode');
}
}

View File

@ -7,7 +7,7 @@ import { Content } from '../content/content';
import { Img } from '../img/img';
import { isBlank, isFunction, isPresent } from '../../util/util';
import { Platform } from '../../platform/platform';
import { ViewController } from '../nav/view-controller';
import { ViewController } from '../../navigation/view-controller';
import { VirtualCell, VirtualData, VirtualNode } from './virtual-util';
import { VirtualFooter, VirtualHeader, VirtualItem } from './virtual-item';
@ -99,7 +99,7 @@ import { VirtualFooter, VirtualHeader, VirtualItem } from './virtual-item';
*
* It's also important to know that Ionic's default item sizes have
* slightly different heights between platforms, which is perfectly fine.
*
*
*
*
* ### Images Within Virtual Scroll
@ -117,7 +117,7 @@ import { VirtualFooter, VirtualHeader, VirtualItem } from './virtual-item';
* makes a HTTP request for the image file. HTTP requests, image
* decoding, and image rendering can cause issues while scrolling. For virtual
* scrolling, the natural effects of the `<img>` are not desirable features.
*
*
* Note: `<ion-img>` should only be used with Virtual Scroll. If you are using
* an image outside of Virtual Scroll you should use the standard `<img>` tag.
*
@ -155,29 +155,29 @@ import { VirtualFooter, VirtualHeader, VirtualItem } from './virtual-item';
selector: '[virtualScroll]'
})
export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
private _trackBy: TrackByFn;
private _differ: IterableDiffer;
private _unreg: Function;
private _init: boolean;
private _rafId: number;
private _tmId: number;
private _hdrFn: Function;
private _ftrFn: Function;
private _records: any[] = [];
private _cells: VirtualCell[] = [];
private _nodes: VirtualNode[] = [];
private _vHeight: number = 0;
private _lastCheck: number = 0;
private _data: VirtualData = {
_trackBy: TrackByFn;
_differ: IterableDiffer;
_unreg: Function;
_init: boolean;
_rafId: number;
_tmId: number;
_hdrFn: Function;
_ftrFn: Function;
_records: any[] = [];
_cells: VirtualCell[] = [];
_nodes: VirtualNode[] = [];
_vHeight: number = 0;
_lastCheck: number = 0;
_data: VirtualData = {
scrollTop: 0,
};
private _eventAssist: boolean;
private _queue: number = null;
_eventAssist: boolean;
_queue: number = null;
@ContentChild(VirtualItem) private _itmTmp: VirtualItem;
@ContentChild(VirtualHeader) private _hdrTmp: VirtualHeader;
@ContentChild(VirtualFooter) private _ftrTmp: VirtualFooter;
@ContentChildren(Img) private _imgs: QueryList<Img>;
@ContentChild(VirtualItem) _itmTmp: VirtualItem;
@ContentChild(VirtualHeader) _hdrTmp: VirtualHeader;
@ContentChild(VirtualFooter) _ftrTmp: VirtualFooter;
@ContentChildren(Img) _imgs: QueryList<Img>;
/**
* @input {array} The data that builds the templates within the virtual scroll.
@ -285,7 +285,7 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
*/
@Input() set headerFn(val: Function) {
if (isFunction(val)) {
this._hdrFn = val.bind((this._ctrl && this._ctrl.instance) || this);
this._hdrFn = val.bind((this._ctrl && this._ctrl._cmp) || this);
}
}
@ -298,7 +298,7 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
*/
@Input() set footerFn(val: Function) {
if (isFunction(val)) {
this._ftrFn = val.bind((this._ctrl && this._ctrl.instance) || this);
this._ftrFn = val.bind((this._ctrl && this._ctrl._cmp) || this);
}
}
@ -352,7 +352,7 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
if (!this.approxItemHeight) {
this.approxItemHeight = '40px';
console.warn('approxItemHeight set to default: Provide approxItemHeight to ensure proper virtual scroll rendering');
console.warn('Virtual Scroll: Please provide an "approxItemHeight" input to ensure proper virtual scroll rendering');
}
}
}
@ -387,7 +387,7 @@ export class VirtualScroll implements DoCheck, AfterContentInit, OnDestroy {
// good to go, we already have good dimension data
done();
} else {
} else {
// ******** DOM READ ****************
calcDimensions(self._data, self._elementRef.nativeElement.parentElement,
self.approxItemWidth, self.approxItemHeight,

View File

@ -1,4 +1,4 @@
import { Directive, Input, ViewContainerRef, TemplateRef, EmbeddedViewRef, } from '@angular/core';
import { ViewContainerRef, TemplateRef, EmbeddedViewRef, } from '@angular/core';
import { CSS } from '../../util/dom';
@ -135,7 +135,6 @@ export function populateNodeData(startCellIndex: number, endCellIndex: number, v
let node: VirtualNode;
let availableNode: VirtualNode;
let cell: VirtualCell;
let previousCell: VirtualCell;
let isAlreadyRendered: boolean;
let lastRecordIndex = (records.length - 1);
let viewInsertIndex: number = null;
@ -428,7 +427,7 @@ export function writeToNodes(nodes: VirtualNode[], cells: VirtualCell[], totalRe
if (element) {
// ******** DOM WRITE ****************
element.style[CSS.transform] = node.lastTransform = transform;
(<any>element.style)[CSS.transform] = node.lastTransform = transform;
// ******** DOM WRITE ****************
element.classList.add('virtual-position');