diff --git a/ionic/components/content/content.ts b/ionic/components/content/content.ts index a1848f261e..145169921b 100644 --- a/ionic/components/content/content.ts +++ b/ionic/components/content/content.ts @@ -305,7 +305,7 @@ export class Content { */ add_padding(newPadding) { if (newPadding > this._padding) { - console.debug('add_padding', newPadding); + console.debug('content add padding', newPadding); this._padding = newPadding; this._scrollEle.style.paddingBottom = newPadding + 'px'; diff --git a/ionic/components/nav/nav-controller.ts b/ionic/components/nav/nav-controller.ts index bac033ad60..aca8e14da1 100644 --- a/ionic/components/nav/nav-controller.ts +++ b/ionic/components/nav/nav-controller.ts @@ -100,30 +100,31 @@ import {raf, rafFrames} from '../../util/dom'; * @see {@link /docs/v2/components#navigation Navigation Component Docs} */ export class NavController extends Ion { - private _views: Array = []; - private _trnsTime: number = 0; - private _trnsDelay: any; - private _sbTrans: any = null; - private _sbEnabled: any; - private _sbThreshold: any; - public sbGesture: any; - private initZIndex: number = 10; + protected _ids: number = -1; + protected _sbEnabled: any; + protected _sbThreshold: any; + protected _sbTrans: any = null; + protected _trnsDelay: any; + protected _trnsTime: number = 0; + protected _views: Array = []; + protected _zIndex: number = 10; + public id: number; - private _ids: number = -1; public providers: ResolvedProvider[]; public router: any; + public sbGesture: any; constructor( - public parent: NavController, + public parent: any, public app: IonicApp, public config: Config, public keyboard: Keyboard, elementRef: ElementRef, - private _anchorName: string, - private _compiler: Compiler, - private _viewManager: AppViewManager, - private _zone: NgZone, - private _renderer: Renderer + protected _anchorName: string, + protected _compiler: Compiler, + protected _viewManager: AppViewManager, + protected _zone: NgZone, + protected _renderer: Renderer ) { super(elementRef); @@ -555,7 +556,7 @@ export class NavController extends Ion { * @param {Object} [opts={}] Any options you want to use pass to transtion * @returns {Promise} Returns a promise when the view has been removed */ - remove(index: number, opts = {}): Promise { + remove(index: number, opts: any = {}): Promise { if (index < 0 || index >= this._views.length) { return Promise.reject("index out of range"); } @@ -1067,7 +1068,7 @@ export class NavController extends Ion { let enteringPageRef = enteringView && enteringView.pageRef(); if (enteringPageRef) { if (!leavingView || !leavingView.isLoaded()) { - enteringView.zIndex = this.initZIndex; + enteringView.zIndex = this._zIndex; } else if (direction === 'back') { // moving back @@ -1391,7 +1392,7 @@ export class NavController extends Ion { * @param {Index} The index of the page you want to get * @returns {Component} Returns the component that matches the index given */ - getByIndex(index: number): ViewController { + getByIndex(index: number): any { if (index < this._views.length && index > -1) { return this._views[index]; } diff --git a/ionic/components/nav/view-controller.ts b/ionic/components/nav/view-controller.ts index 2bbbacd713..985fc8d04b 100644 --- a/ionic/components/nav/view-controller.ts +++ b/ionic/components/nav/view-controller.ts @@ -18,23 +18,26 @@ import {Navbar} from '../navbar/navbar'; * ``` */ export class ViewController { - public instance: any = {}; - public state: number = 0; + private _cntDir: any; + private _cntRef: ElementRef; private _destroys: Array = []; private _loaded: boolean = false; - public shouldDestroy: boolean = false; - public shouldCache: boolean = false; - public viewType: string = ''; - public id: string; private _leavingOpts: any = null; - private _onDismiss: Function = null; - protected _nav: NavController; + private _nbDir: Navbar; private _nbTmpRef: TemplateRef; private _nbVwRef: ViewContainerRef; + private _onDismiss: Function = null; private _pgRef: ElementRef; - private _cntRef: ElementRef; - private _nbDir: Navbar; - private _cntDir: any; + protected _nav: NavController; + + id: string; + instance: any = {}; + state: number = 0; + shouldDestroy: boolean = false; + shouldCache: boolean = false; + viewType: string = ''; + onReady: any; + @Output() private _emitter: EventEmitter = new EventEmitter(); constructor(public componentType?: Type, public data: any = {}) {} diff --git a/ionic/components/tabs/tab-button.ts b/ionic/components/tabs/tab-button.ts new file mode 100644 index 0000000000..399ab1d7bb --- /dev/null +++ b/ionic/components/tabs/tab-button.ts @@ -0,0 +1,49 @@ +import {Component, Directive, ElementRef, Optional, Host, forwardRef, ViewContainerRef, HostListener, EventEmitter, Output, Input, Renderer} from 'angular2/core'; + +import {Tab} from './tab'; +import {Config} from '../../config/config'; + + +/** + * @private + */ +@Directive({ + selector: '.tab-button', + host: { + '[attr.id]': 'tab._btnId', + '[attr.aria-controls]': 'tab._panelId', + '[attr.aria-selected]': 'tab.isSelected', + '[class.has-title]': 'hasTitle', + '[class.has-icon]': 'hasIcon', + '[class.has-title-only]': 'hasTitleOnly', + '[class.icon-only]': 'hasIconOnly', + '[class.disable-hover]': 'disHover' + } +}) +export class TabButton { + private disHover: boolean; + private hasTitle: boolean; + private hasIcon: boolean; + private hasTitleOnly: boolean; + private hasIconOnly: boolean; + + @Input() tab: Tab; + @Output() select: EventEmitter = new EventEmitter(); + + constructor(config: Config) { + this.disHover = (config.get('hoverCSS') === false); + } + + ngOnInit() { + this.tab.btn = this; + this.hasTitle = !!this.tab.tabTitle; + this.hasIcon = !!this.tab.tabIcon; + this.hasTitleOnly = (this.hasTitle && !this.hasIcon); + this.hasIconOnly = (this.hasIcon && !this.hasTitle); + } + + @HostListener('click') + private onClick() { + this.select.emit(this.tab); + } +} \ No newline at end of file diff --git a/ionic/components/tabs/tab-highlight.ts b/ionic/components/tabs/tab-highlight.ts new file mode 100644 index 0000000000..181934c325 --- /dev/null +++ b/ionic/components/tabs/tab-highlight.ts @@ -0,0 +1,31 @@ +import {Directive, ElementRef} from 'angular2/core'; + +import {rafFrames} from '../../util/dom'; + +/** + * @private + */ +@Directive({ + selector: 'tab-highlight' +}) +export class TabHighlight { + private _init: boolean; + + constructor(private _elementRef: ElementRef) {} + + select(tab) { + rafFrames(3, () => { + let d = tab.btn.getDimensions(); + let ele = this._elementRef.nativeElement; + ele.style.transform = 'translate3d(' + d.left + 'px,0,0) scaleX(' + d.width + ')'; + + if (!this._init) { + this._init = true; + rafFrames(6, () => { + ele.classList.add('animate'); + }); + } + }); + } + +} \ No newline at end of file diff --git a/ionic/components/tabs/tab.ts b/ionic/components/tabs/tab.ts index 158ca6370b..95513b9a5c 100644 --- a/ionic/components/tabs/tab.ts +++ b/ionic/components/tabs/tab.ts @@ -1,5 +1,5 @@ -import {ChangeDetectorRef, Component, Directive, Host, ElementRef, Compiler, AppViewManager, NgZone, Renderer} from 'angular2/core'; -import {EventEmitter, Output} from 'angular2/core'; +import {Component, Directive, Host, Inject, forwardRef, ElementRef, Compiler, AppViewManager, NgZone, Renderer, Type} from 'angular2/core'; +import {EventEmitter, Input, Output} from 'angular2/core'; import {IonicApp} from '../app/app'; import {Config} from '../../config/config'; @@ -7,6 +7,7 @@ import {Keyboard} from '../../util/keyboard'; import {NavController} from '../nav/nav-controller'; import {ViewController} from '../nav/view-controller'; import {Tabs} from './tabs'; +import {TabButton} from './tab-button'; /** @@ -83,11 +84,6 @@ import {Tabs} from './tabs'; */ @Component({ selector: 'ion-tab', - inputs: [ - 'root', - 'tabTitle', - 'tabIcon' - ], host: { '[class.show-tab]': 'isSelected', '[attr.id]': '_panelId', @@ -97,10 +93,20 @@ import {Tabs} from './tabs'; template: '' }) export class Tab extends NavController { + public isSelected: boolean; + private _isInitial: boolean; + private _panelId: string; + private _btnId: string; + private _loaded: boolean; + private _loadTimer: any; + btn: TabButton; + @Input() root: Type; + @Input() tabTitle: string; + @Input() tabIcon: string; @Output() select: EventEmitter = new EventEmitter(); constructor( - @Host() parentTabs: Tabs, + @Inject(forwardRef(() => Tabs)) parentTabs: Tabs, app: IonicApp, config: Config, keyboard: Keyboard, @@ -108,11 +114,10 @@ export class Tab extends NavController { compiler: Compiler, viewManager: AppViewManager, zone: NgZone, - renderer: Renderer, - cd: ChangeDetectorRef + renderer: Renderer ) { // A Tab is a NavController for its child pages - super(parentTabs, app, config, keyboard, elementRef, 'contents', compiler, viewManager, zone, renderer, cd); + super(parentTabs, app, config, keyboard, elementRef, 'contents', compiler, viewManager, zone, renderer); this._isInitial = parentTabs.add(this); @@ -146,7 +151,7 @@ export class Tab extends NavController { /** * @private */ - load(opts, done) { + load(opts, done?: Function) { if (!this._loaded && this.root) { this.push(this.root, null, opts, done); this._loaded = true; @@ -186,13 +191,6 @@ export class Tab extends NavController { this.hideNavbars(!isSelected); } - /** - * @private - */ - emitSelect() { - this.select.emit(); - } - /** * @private */ @@ -214,7 +212,7 @@ export class Tab extends NavController { * } * ``` * - * @returns {Number} Returns the index of this page within its NavController. + * @returns {number} Returns the index of this page within its NavController. * */ get index() { diff --git a/ionic/components/tabs/tabs.ts b/ionic/components/tabs/tabs.ts index cd17bc659f..9e53c668b1 100644 --- a/ionic/components/tabs/tabs.ts +++ b/ionic/components/tabs/tabs.ts @@ -1,9 +1,12 @@ -import {Component, Directive, ElementRef, Optional, Host, forwardRef, ViewContainerRef, HostListener, EventEmitter, Output, Input, Renderer} from 'angular2/core'; +import {Component, Directive, ElementRef, Optional, Host, forwardRef, ViewContainerRef, ViewChild, ViewChildren, EventEmitter, Output, Input, Renderer} from 'angular2/core'; import {NgFor, NgIf} from 'angular2/common'; -import {Ion} from '../ion'; -import {Attr} from '../app/id'; +import {IonicApp} from '../app/app'; import {Config} from '../../config/config'; +import {Tab} from './tab'; +import {TabButton} from './tab-button'; +import {TabHighlight} from './tab-highlight'; +import {Ion} from '../ion'; import {Platform} from '../../platform/platform'; import {NavController} from '../nav/nav-controller'; import {ViewController} from '../nav/view-controller'; @@ -56,42 +59,50 @@ import {isUndefined} from '../../util/util'; Icon, NgFor, NgIf, - Attr, - forwardRef(() => TabButton), - forwardRef(() => TabHighlight), + TabButton, + TabHighlight, forwardRef(() => TabNavBarAnchor) ] }) export class Tabs extends Ion { - private tabs: Array; - @Input() tabbarPlacement: string; + private _ids: number = -1; + private _tabs: Array = []; + private _onReady = null; + private _useHighlight: boolean; + + id: number; + navbarContainerRef: ViewContainerRef; + subPages: boolean; + + @Input() preloadTabs: any; @Input() tabbarIcons: string; - @Input() preloadTabs: boolean; - @Output() change: EventEmitter = new EventEmitter(); + @Input() tabbarPlacement: string; + @Output() change: EventEmitter = new EventEmitter(); + + @ViewChild(TabHighlight) private _highlight: TabHighlight; + @ViewChildren(TabButton) private _btns; - constructor( - elementRef: ElementRef, + constructor( @Optional() viewCtrl: ViewController, - @Optional() navCtrl: NavController, + @Optional() public parent: NavController, + private _app: IonicApp, private _config: Config, + private _elementRef: ElementRef, private _platform: Platform, private _renderer: Renderer ) { - super(elementRef); - this.parent = navCtrl; - this.subPages = _config.get('tabSubPages'); - - this._tabs = []; - this._id = ++tabIds; - this._ids = -1; - this._onReady = null; + super(_elementRef); + + this.id = ++tabIds; + this.subPages = _config.getBoolean('tabSubPages'); + this._useHighlight = _config.getBoolean('tabbarHighlight'); // Tabs may also be an actual ViewController which was navigated to // if Tabs is static and not navigated to within a NavController // then skip this and don't treat it as it's own ViewController if (viewCtrl) { viewCtrl.setContent(this); - viewCtrl.setContentRef(elementRef); + viewCtrl.setContentRef(_elementRef); viewCtrl.onReady = (done) => { this._onReady = done; @@ -102,18 +113,24 @@ export class Tabs extends Ion { /** * @private */ - ngOnInit() { + ngAfterViewInit() { this.preloadTabs = (this.preloadTabs !== "false" && this.preloadTabs !== false); this._setConfig('tabbarPlacement', 'bottom'); this._setConfig('tabbarIcons', 'top'); this._setConfig('preloadTabs', false); - if (this._highlight) { + if (this._useHighlight) { this._platform.onResize(() => { this._highlight.select(this.getSelected()); }); } + + this._btns.toArray().forEach((tabButton: TabButton) => { + tabButton.select.subscribe((tab: Tab) => { + this.select(tab); + }); + }); } _setConfig(attrKey, fallback) { @@ -121,26 +138,26 @@ export class Tabs extends Ion { if (isUndefined(val)) { val = this._config.get(attrKey); } - this._renderer.setElementAttribute(this.elementRef, attrKey, val); + this._renderer.setElementAttribute(this._elementRef, attrKey, val); } /** * @private */ add(tab) { - tab.id = this._id + '-' + (++this._ids); + tab.id = this.id + '-' + (++this._ids); this._tabs.push(tab); return (this._tabs.length === 1); } /** - * @param {Number} index Index of the tab you want to select + * @param {number} index Index of the tab you want to select */ select(tabOrIndex) { let selectedTab = (typeof tabOrIndex === 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex); if (!selectedTab) { - return Promise.reject(); + return; } let deselectedTab = this.getSelected(); @@ -167,7 +184,7 @@ export class Tabs extends Ion { selectedTab.load(opts, () => { - selectedTab.emitSelect(); + selectedTab.select.emit(selectedTab); this.change.emit(selectedTab); if (selectedTab.root) { @@ -180,7 +197,9 @@ export class Tabs extends Ion { }); } - this._highlight && this._highlight.select(selectedTab); + if (this._useHighlight) { + this._highlight.select(selectedTab); + } selectedPage && selectedPage.didEnter(); deselectedPage && deselectedPage.didLeave(); @@ -195,10 +214,10 @@ export class Tabs extends Ion { } /** - * @param {Number} index Index of the tab you want to get + * @param {number} index Index of the tab you want to get * @returns {Any} Tab Returs the tab who's index matches the one passed */ - getByIndex(index) { + getByIndex(index: number): any { if (index < this._tabs.length && index > -1) { return this._tabs[index]; } @@ -208,7 +227,7 @@ export class Tabs extends Ion { /** * @return {Any} Tab Returns the currently selected tab */ - getSelected() { + getSelected(): Tab { for (let i = 0; i < this._tabs.length; i++) { if (this._tabs[i].isSelected) { return this._tabs[i]; @@ -220,7 +239,7 @@ export class Tabs extends Ion { /** * @private */ - getIndex(tab) { + getIndex(tab: Tab): number { return this._tabs.indexOf(tab); } @@ -277,77 +296,6 @@ export class Tabs extends Ion { let tabIds = -1; -/** - * @private - */ -@Directive({ - selector: '.tab-button', - inputs: ['tab'], - host: { - '[attr.id]': 'tab._btnId', - '[attr.aria-controls]': 'tab._panelId', - '[attr.aria-selected]': 'tab.isSelected', - '[class.has-title]': 'hasTitle', - '[class.has-icon]': 'hasIcon', - '[class.has-title-only]': 'hasTitleOnly', - '[class.icon-only]': 'hasIconOnly', - '[class.disable-hover]': 'disHover' - } -}) -class TabButton extends Ion { - constructor(@Host() tabs: Tabs, config: Config, elementRef: ElementRef) { - super(elementRef); - this.tabs = tabs; - this.disHover = (config.get('hoverCSS') === false); - } - - ngOnInit() { - this.tab.btn = this; - this.hasTitle = !!this.tab.tabTitle; - this.hasIcon = !!this.tab.tabIcon; - this.hasTitleOnly = (this.hasTitle && !this.hasIcon); - this.hasIconOnly = (this.hasIcon && !this.hasTitle); - } - - @HostListener('click') - private onClick() { - this.tabs.select(this.tab); - } -} - - -/** - * @private - */ -@Directive({ - selector: 'tab-highlight' -}) -class TabHighlight { - constructor(@Host() tabs: Tabs, config: Config, elementRef: ElementRef) { - if (config.get('tabbarHighlight')) { - tabs._highlight = this; - this.elementRef = elementRef; - } - } - - select(tab) { - rafFrames(3, () => { - let d = tab.btn.getDimensions(); - let ele = this.elementRef.nativeElement; - ele.style.transform = 'translate3d(' + d.left + 'px,0,0) scaleX(' + d.width + ')'; - - if (!this.init) { - this.init = true; - rafFrames(6, () => { - ele.classList.add('animate'); - }); - } - }); - } - -} - - /** * @private */ diff --git a/ionic/config/config.ts b/ionic/config/config.ts index f030857cab..2426f9641a 100644 --- a/ionic/config/config.ts +++ b/ionic/config/config.ts @@ -183,7 +183,7 @@ export class Config { * * @param {String} [key] - the key for the config value */ - get(key) { + get(key: string): any { if (!isDefined(this._c[key])) { if (!isDefined(key)) { @@ -280,6 +280,11 @@ export class Config { return this._c[key]; } + + getBoolean(key: string): boolean { + let val = this.get(key); + return (val || val === 'true') ? true : false; + } /** * @private