From bc7d328bc0e2b671ee1a49ffbf3b31a0e9020a6f Mon Sep 17 00:00:00 2001 From: Brandy Carney Date: Tue, 13 Sep 2016 17:11:33 -0500 Subject: [PATCH] refactor(components): add color/mode properties --- src/components/badge/badge.ts | 44 ++-- src/components/button/button.ts | 107 +++++----- src/components/checkbox/checkbox.ts | 114 +++++------ src/components/chip/chip.ts | 44 ++-- src/components/content/content.ts | 91 ++++----- src/components/datetime/datetime.ts | 83 +++++--- src/components/icon/icon.ts | 93 ++++----- src/components/icon/test/basic/main.html | 2 +- src/components/input/input-base.ts | 174 ++++++---------- src/components/input/input.ts | 237 ++++++++++++++++++++-- src/components/input/native-input.ts | 24 +-- src/components/item/item.ts | 151 ++++++-------- src/components/label/label.ts | 58 ++---- src/components/modal/modal-component.ts | 151 ++++++-------- src/components/navbar/navbar.ts | 246 +++++++---------------- src/components/radio/radio-button.ts | 123 ++++++------ src/components/range/range.ts | 151 ++++++-------- src/components/searchbar/searchbar.ts | 68 +++---- src/components/segment/segment.ts | 77 +++---- src/components/spinner/spinner.ts | 68 ++----- src/components/toast/toast-component.ts | 126 +++++------- src/components/toggle/toggle.ts | 134 ++++++------ src/components/toolbar/toolbar-item.ts | 13 +- src/components/toolbar/toolbar-title.ts | 17 +- src/components/toolbar/toolbar.ts | 128 ++++-------- 25 files changed, 1174 insertions(+), 1350 deletions(-) diff --git a/src/components/badge/badge.ts b/src/components/badge/badge.ts index e6e3c624e9..d46e1f9a79 100644 --- a/src/components/badge/badge.ts +++ b/src/components/badge/badge.ts @@ -1,6 +1,7 @@ import { Directive, ElementRef, Input, Renderer } from '@angular/core'; import { Config } from '../../config/config'; +import { Ion } from '../ion'; /** @@ -13,43 +14,28 @@ import { Config } from '../../config/config'; @Directive({ selector: 'ion-badge' }) -export class Badge { - /** @internal */ - _color: string; +export class Badge 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( - config: Config, - 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('badge', 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, `badge-${color}`, isAdd); - } + @Input() + set mode(val: string) { + this._setMode('badge', val); } + + constructor(config: Config, elementRef: ElementRef, renderer: Renderer) { + super(config, elementRef, renderer); + + this.mode = config.get('mode'); + } + } diff --git a/src/components/button/button.ts b/src/components/button/button.ts index e8289e9f5d..db8c49eafd 100644 --- a/src/components/button/button.ts +++ b/src/components/button/button.ts @@ -1,6 +1,7 @@ import { Attribute, ChangeDetectionStrategy, Component, ElementRef, Input, Renderer, ViewEncapsulation } from '@angular/core'; import { Config } from '../../config/config'; +import { Ion } from '../ion'; import { isTrueProperty } from '../../util/util'; @@ -90,37 +91,34 @@ import { isTrueProperty } from '../../util/util'; */ @Component({ selector: '[ion-button]', - // NOTE: template must not contain spaces between elements - template: '', + template: + '' + + '' + + '' + + '
', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, }) -export class Button { - /** @internal */ +export class Button extends Ion { + /** @private */ _role: string = 'button'; // bar-button - /** @internal */ - _mt: boolean = false; // menutoggle + /** @private */ + _mt: boolean; // menutoggle - /** @internal */ - _size: string = null; // large/small/default + /** @private */ + _size: string; // large/small/default - /** @internal */ + /** @private */ _style: string = 'default'; // outline/clear/solid - /** @internal */ - _shape: string = null; // round/fab + /** @private */ + _shape: string; // round/fab - /** @internal */ - _display: string = null; // block/full + /** @private */ + _display: string; // block/full - /** @internal */ - _color: string = null; // primary/secondary - - /** @internal */ - _disabled: boolean = false; // disabled - - /** @internal */ + /** @private */ _init: boolean; /** @@ -203,9 +201,20 @@ export class Button { this._attr('_display', 'full', val); } + /** + * @input {string} A button that fills its parent container without a border-radius or borders on the left/right. + */ + @Input() + set mode(val: string) { + this._assignCss(false); + this._mode = val; + this._assignCss(true); + } + + /** @private */ _attr(type: string, attrName: string, attrValue: boolean) { if (type === '_style') { - this._setColor(this._color, isTrueProperty(attrValue)); + this._updateColor(this._color, isTrueProperty(attrValue)); } this._setClass((this)[type], false); if (isTrueProperty(attrValue)) { @@ -224,24 +233,23 @@ export class Button { */ @Input() set color(val: string) { - this._updateColor(val); + this._updateColor(this._color, false); + this._updateColor(val, true); + this._color = val; } constructor( @Attribute('menuToggle') menuToggle: string, @Attribute('ion-button') ionButton: string, config: Config, - private _elementRef: ElementRef, - private _renderer: Renderer + elementRef: ElementRef, + renderer: Renderer ) { - let element = _elementRef.nativeElement; + super(config, elementRef, renderer); + this._mode = config.get('mode'); if (config.get('hoverCSS') === false) { - _renderer.setElementClass(element, 'disable-hover', true); - } - - if (element.hasAttribute('disabled')) { - this._disabled = true; + this.setElementClass('disable-hover', true); } if (ionButton.trim().length > 0) { @@ -255,30 +263,11 @@ export class Button { } } - /** - * @private - */ ngAfterContentInit() { this._init = true; this._assignCss(true); } - /** - * @internal - */ - _updateColor(newColor: string) { - this._setColor(this._color, false); - this._setColor(newColor, true); - this._color = newColor; - } - - /** - * @private - */ - addClass(className: string) { - this._renderer.setElementClass(this._elementRef.nativeElement, className, true); - } - /** * @private */ @@ -289,36 +278,38 @@ export class Button { } /** - * @internal + * @private */ _assignCss(assignCssClass: boolean) { let role = this._role; if (role) { - this._renderer.setElementClass(this._elementRef.nativeElement, role, assignCssClass); // button + this.setElementClass(role, assignCssClass); // button + this.setElementClass(`${role}-${this._mode}`, assignCssClass); // button this._setClass('menutoggle', this._mt); // menutoggle - this._setClass(this._style, assignCssClass); // button-clear this._setClass(this._shape, assignCssClass); // button-round this._setClass(this._display, assignCssClass); // button-full this._setClass(this._size, assignCssClass); // button-small - this._setColor(this._color, assignCssClass); // button-secondary, bar-button-secondary + this._updateColor(this._color, assignCssClass); // button-secondary, bar-button-secondary } } /** - * @internal + * @private */ _setClass(type: string, assignCssClass: boolean) { if (type && this._init) { - this._renderer.setElementClass(this._elementRef.nativeElement, this._role + '-' + type.toLowerCase(), assignCssClass); + type = type.toLocaleLowerCase(); + this.setElementClass(`${this._role}-${type}`, assignCssClass); + this.setElementClass(`${this._role}-${type}-${this._mode}`, assignCssClass); } } /** - * @internal + * @private */ - _setColor(color: string, isAdd: boolean) { + _updateColor(color: string, isAdd: boolean) { if (color && this._init) { // The class should begin with the button role // button, bar-button @@ -331,7 +322,7 @@ export class Button { className += (style !== null && style !== '' && style !== 'default' ? '-' + style.toLowerCase() : ''); if (color !== null && color !== '') { - this._renderer.setElementClass(this._elementRef.nativeElement, `${className}-${color}`, isAdd); + this.setElementClass(`${className}-${this._mode}-${color}`, isAdd); } } } diff --git a/src/components/checkbox/checkbox.ts b/src/components/checkbox/checkbox.ts index 8921be553b..2082030ff9 100644 --- a/src/components/checkbox/checkbox.ts +++ b/src/components/checkbox/checkbox.ts @@ -1,13 +1,17 @@ -import { AfterContentInit, Component, ElementRef, EventEmitter, forwardRef, HostListener, Input, OnDestroy, Optional, Output, Provider, Renderer, ViewEncapsulation } from '@angular/core'; +import { AfterContentInit, Component, ElementRef, EventEmitter, forwardRef, HostListener, Input, OnDestroy, Optional, Output, Renderer, ViewEncapsulation } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { Config } from '../../config/config'; import { Form } from '../../util/form'; +import { Ion } from '../ion'; import { isTrueProperty } from '../../util/util'; import { Item } from '../item/item'; -export const CHECKBOX_VALUE_ACCESSOR = new Provider( - NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => Checkbox), multi: true}); - +export const CHECKBOX_VALUE_ACCESSOR: any = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => Checkbox), + multi: true +}; /** * @name Checkbox @@ -49,50 +53,53 @@ export const CHECKBOX_VALUE_ACCESSOR = new Provider( */ @Component({ selector: 'ion-checkbox', - template: ` -
-
-
- - `, + template: + '
' + + '
' + + '
' + + '', host: { '[class.checkbox-disabled]': '_disabled' }, providers: [CHECKBOX_VALUE_ACCESSOR], encapsulation: ViewEncapsulation.None, }) -export class Checkbox implements AfterContentInit, ControlValueAccessor, OnDestroy { - private _checked: boolean = false; - private _init: boolean; - private _disabled: boolean = false; - private _labelId: string; - private _fn: Function; - - /** internal */ - private _color: string; - - /** - * @private - */ +export class Checkbox extends Ion implements AfterContentInit, ControlValueAccessor, OnDestroy { + /** @private */ + _checked: boolean = false; + /** @private */ + _init: boolean; + /** @private */ + _disabled: boolean = false; + /** @private */ + _labelId: string; + /** @private */ + _fn: Function; + /** @private */ id: string; /** * @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`. */ @Input() - get color(): string { - return this._color; + set color(val: string) { + this._setColor('checkbox', val); } - set color(value: string) { - this._updateColor(value); + /** + * @input {string} The mode to apply to this component. + */ + @Input() + set mode(val: string) { + this._setMode('checkbox', val); } /** @@ -101,35 +108,22 @@ export class Checkbox implements AfterContentInit, ControlValueAccessor, OnDestr @Output() ionChange: EventEmitter = new EventEmitter(); constructor( + config: Config, private _form: Form, @Optional() private _item: Item, - private _elementRef: ElementRef, - private _renderer: Renderer + elementRef: ElementRef, + renderer: Renderer ) { + super(config, elementRef, renderer); + + this.mode = config.get('mode'); + _form.register(this); if (_item) { this.id = 'chk-' + _item.registerInput('checkbox'); this._labelId = 'lbl-' + _item.id; - this._item.setCssClass('item-checkbox', true); - } - } - - /** - * @internal - */ - _updateColor(newColor: string) { - this._setElementColor(this._color, false); - this._setElementColor(newColor, true); - this._color = newColor; - } - - /** - * @internal - */ - _setElementColor(color: string, isAdd: boolean) { - if (color !== null && color !== '') { - this._renderer.setElementClass(this._elementRef.nativeElement, `checkbox-${color}`, isAdd); + this._item.setElementClass('item-checkbox', true); } } @@ -137,7 +131,7 @@ export class Checkbox implements AfterContentInit, ControlValueAccessor, OnDestr * @private */ @HostListener('click', ['$event']) - private _click(ev: UIEvent) { + _click(ev: UIEvent) { console.debug('checkbox, checked'); ev.preventDefault(); ev.stopPropagation(); @@ -160,13 +154,13 @@ export class Checkbox implements AfterContentInit, ControlValueAccessor, OnDestr /** * @private */ - private _setChecked(isChecked: boolean) { - if (isChecked !== this._checked) { + _setChecked(isChecked: boolean) { + if (!this._disabled && isChecked !== this._checked) { this._checked = isChecked; if (this._init) { this.ionChange.emit(this); } - this._item && this._item.setCssClass('item-checkbox-checked', isChecked); + this._item && this._item.setElementClass('item-checkbox-checked', isChecked); } } @@ -205,7 +199,7 @@ export class Checkbox implements AfterContentInit, ControlValueAccessor, OnDestr set disabled(val: boolean) { this._disabled = isTrueProperty(val); - this._item && this._item.setCssClass('item-checkbox-disabled', this._disabled); + this._item && this._item.setElementClass('item-checkbox-disabled', this._disabled); } /** diff --git a/src/components/chip/chip.ts b/src/components/chip/chip.ts index 6bb498b23d..075710d35a 100644 --- a/src/components/chip/chip.ts +++ b/src/components/chip/chip.ts @@ -1,5 +1,8 @@ import { Directive, ElementRef, Input, Renderer } from '@angular/core'; +import { Config } from '../../config/config'; +import { Ion } from '../ion'; + /** * @name Chip * @module ionic @@ -90,43 +93,28 @@ import { Directive, ElementRef, Input, Renderer } from '@angular/core'; @Directive({ selector: 'ion-chip' }) -export class Chip { - /** @internal */ - _color: string; +export class Chip 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('chip', 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, `chip-${color}`, isAdd); - } + @Input() + set mode(val: string) { + this._setMode('chip', val); + } + + constructor(config: Config, elementRef: ElementRef, renderer: Renderer) { + super(config, elementRef, renderer); + + this.mode = config.get('mode'); } } diff --git a/src/components/content/content.ts b/src/components/content/content.ts index dba362cb52..e9e023f801 100644 --- a/src/components/content/content.ts +++ b/src/components/content/content.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, ElementRef, Input, NgZone, Optional, ViewEncapsulation } from '@angular/core'; +import { ChangeDetectionStrategy, Component, ElementRef, Input, NgZone, Optional, Renderer, ViewEncapsulation } from '@angular/core'; import { App } from '../app/app'; import { Ion } from '../ion'; @@ -7,7 +7,7 @@ import { Keyboard } from '../../util/keyboard'; import { nativeRaf, nativeTimeout, transitionEnd} from '../../util/dom'; import { ScrollView } from '../../util/scroll-view'; import { Tabs } from '../tabs/tabs'; -import { ViewController } from '../nav/view-controller'; +import { ViewController } from '../../navigation/view-controller'; import { isTrueProperty } from '../../util/util'; @@ -103,34 +103,38 @@ import { isTrueProperty } from '../../util/util'; @Component({ selector: 'ion-content', template: - '' + + '
' + '' + - '' + + '
' + '' + '', - changeDetection: ChangeDetectionStrategy.OnPush, - encapsulation: ViewEncapsulation.None, host: { '[class.statusbar-padding]': '_sbPadding' - } + }, + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None }) export class Content extends Ion { - private _paddingTop: number; - private _paddingRight: number; - private _paddingBottom: number; - private _paddingLeft: number; - private _scrollPadding: number; - private _headerHeight: number; - private _footerHeight: number; - private _tabbarHeight: number; - private _tabsPlacement: string; - private _inputPolling: boolean = false; - private _scroll: ScrollView; - private _scLsn: Function; - private _sbPadding: boolean; - private _fullscreen: boolean; - private _scrollEle: HTMLElement; - private _footerEle: HTMLElement; + _paddingTop: number; + _paddingRight: number; + _paddingBottom: number; + _paddingLeft: number; + _scrollPadding: number; + _headerHeight: number; + _footerHeight: number; + _tabbarHeight: number; + _tabsPlacement: string; + _inputPolling: boolean = false; + _scroll: ScrollView; + _scLsn: Function; + _sbPadding: boolean; + _fullscreen: boolean; + _footerEle: HTMLElement; + + /* + * @private + */ + _scrollEle: HTMLElement; /** * A number representing how many pixels the top of the content has been @@ -145,20 +149,25 @@ export class Content extends Ion { contentBottom: number; constructor( - private _elementRef: ElementRef, config: Config, - private _app: App, - private _keyboard: Keyboard, - private _zone: NgZone, + elementRef: ElementRef, + renderer: Renderer, + public _app: App, + public _keyboard: Keyboard, + public _zone: NgZone, @Optional() viewCtrl: ViewController, - @Optional() private _tabs: Tabs + @Optional() public _tabs: Tabs ) { - super(_elementRef); + super(config, elementRef, renderer); + + this._mode = config.get('mode'); + this._setMode('content', this._mode); + this._sbPadding = config.getBoolean('statusbarPadding', false); if (viewCtrl) { - viewCtrl.setContent(this); - viewCtrl.setContentRef(_elementRef); + viewCtrl._setContent(this); + viewCtrl._setContentRef(elementRef); } } @@ -232,7 +241,7 @@ export class Content extends Ion { return this._addListener('mousemove', handler); } - private _addListener(type: string, handler: any): Function { + _addListener(type: string, handler: any): Function { if (!this._scrollEle) { return; } // ensure we're not creating duplicates @@ -350,14 +359,6 @@ export class Content extends Ion { return this._scroll.jsScroll(onScrollCallback); } - /** - * @private - * DOM WRITE - */ - addCssClass(className: string) { - this.getNativeElement().classList.add(className); - } - /** * @input {boolean} By default, content is positioned between the headers * and footers. However, using `fullscreen="true"`, the content will be @@ -374,20 +375,12 @@ export class Content extends Ion { this._fullscreen = isTrueProperty(val); } - /** - * @private - * DOM WRITE - */ - removeCssClass(className: string) { - this.getNativeElement().classList.remove(className); - } - /** * @private * DOM WRITE */ setScrollElementStyle(prop: string, val: any) { - this._scrollEle.style[prop] = val; + (this._scrollEle.style)[prop] = val; } /** diff --git a/src/components/datetime/datetime.ts b/src/components/datetime/datetime.ts index 7a859cfe8a..e2254ea44f 100644 --- a/src/components/datetime/datetime.ts +++ b/src/components/datetime/datetime.ts @@ -1,17 +1,20 @@ -import { AfterContentInit, Component, EventEmitter, forwardRef, HostListener, Input, OnDestroy, Optional, Output, Provider, ViewEncapsulation } from '@angular/core'; +import { AfterContentInit, Component, ElementRef, EventEmitter, forwardRef, HostListener, Input, OnDestroy, Optional, Output, Renderer, ViewEncapsulation } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { Config } from '../../config/config'; import { Picker, PickerController } from '../picker/picker'; import { PickerColumn, PickerColumnOption } from '../picker/picker-options'; import { Form } from '../../util/form'; +import { Ion } from '../ion'; import { Item } from '../item/item'; import { merge, isBlank, isPresent, isTrueProperty, isArray, isString } from '../../util/util'; import { dateValueRange, renderDateTime, renderTextFormat, convertFormatToKey, getValueFromFormat, parseTemplate, parseDate, updateDate, DateTimeData, convertDataToISO, daysInMonth, dateSortValue, dateDataSortValue, LocaleData } from '../../util/datetime-util'; -export const DATETIME_VALUE_ACCESSOR = new Provider( - NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => DateTime), multi: true}); - +export const DATETIME_VALUE_ACCESSOR: any = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => DateTime), + multi: true +}; /** * @name DateTime @@ -247,32 +250,32 @@ export const DATETIME_VALUE_ACCESSOR = new Provider( */ @Component({ selector: 'ion-datetime', - template: ` -
{{_text}}
- - `, + template: + '
{{_text}}
' + + '', host: { '[class.datetime-disabled]': '_disabled' }, providers: [DATETIME_VALUE_ACCESSOR], encapsulation: ViewEncapsulation.None, }) -export class DateTime implements AfterContentInit, ControlValueAccessor, OnDestroy { - private _disabled: any = false; - private _labelId: string; - private _text: string = ''; - private _fn: Function; - private _isOpen: boolean = false; - private _min: DateTimeData; - private _max: DateTimeData; - private _value: DateTimeData = {}; - private _locale: LocaleData = {}; +export class DateTime extends Ion implements AfterContentInit, ControlValueAccessor, OnDestroy { + _disabled: any = false; + _labelId: string; + _text: string = ''; + _fn: Function; + _isOpen: boolean = false; + _min: DateTimeData; + _max: DateTimeData; + _value: DateTimeData = {}; + _locale: LocaleData = {}; /** * @private @@ -404,6 +407,14 @@ export class DateTime implements AfterContentInit, ControlValueAccessor, OnDestr */ @Input() pickerOptions: any = {}; + /** + * @input {string} The mode to apply to this component. + */ + @Input() + set mode(val: string) { + this._setMode('datetime', val); + } + /** * @output {any} Any expression to evaluate when the datetime selection has changed. */ @@ -416,20 +427,26 @@ export class DateTime implements AfterContentInit, ControlValueAccessor, OnDestr constructor( private _form: Form, - private _config: Config, + config: Config, + elementRef: ElementRef, + renderer: Renderer, @Optional() private _item: Item, @Optional() private _pickerCtrl: PickerController ) { - this._form.register(this); + super(config, elementRef, renderer); + + this.mode = config.get('mode'); + _form.register(this); + if (_item) { this.id = 'dt-' + _item.registerInput('datetime'); this._labelId = 'lbl-' + _item.id; - this._item.setCssClass('item-datetime', true); + this._item.setElementClass('item-datetime', 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; @@ -440,7 +457,7 @@ export class DateTime implements AfterContentInit, ControlValueAccessor, OnDestr } @HostListener('keyup.space') - private _keyup() { + _keyup() { if (!this._isOpen) { this.open(); } @@ -524,9 +541,9 @@ export class DateTime implements AfterContentInit, ControlValueAccessor, OnDestr let values: any[]; // first see if they have exact values to use for this input - if (isPresent(this[key + 'Values'])) { + if (isPresent((this)[key + 'Values'])) { // user provide exact values for this date part - values = convertToArrayOfNumbers(this[key + 'Values'], key); + values = convertToArrayOfNumbers((this)[key + 'Values'], key); } else { // use the default date part values @@ -699,7 +716,7 @@ export class DateTime implements AfterContentInit, ControlValueAccessor, OnDestr */ checkHasValue(inputValue: any) { if (this._item) { - this._item.setCssClass('input-has-value', !!(inputValue && inputValue !== '')); + this._item.setElementClass('input-has-value', !!(inputValue && inputValue !== '')); } } @@ -761,7 +778,7 @@ export class DateTime implements AfterContentInit, ControlValueAccessor, OnDestr set disabled(val) { this._disabled = isTrueProperty(val); - this._item && this._item.setCssClass('item-datetime-disabled', this._disabled); + this._item && this._item.setElementClass('item-datetime-disabled', this._disabled); } /** diff --git a/src/components/icon/icon.ts b/src/components/icon/icon.ts index c878846fd1..d215130760 100644 --- a/src/components/icon/icon.ts +++ b/src/components/icon/icon.ts @@ -1,6 +1,7 @@ -import { Directive, ElementRef, Renderer, Input } from '@angular/core'; +import { Directive, ElementRef, HostBinding, Input, Renderer } from '@angular/core'; import { Config } from '../../config/config'; +import { Ion } from '../ion'; /** @@ -40,15 +41,19 @@ import { Config } from '../../config/config'; 'role': 'img' } }) -export class Icon { - private _isActive: any; - private _name: string = ''; - private _ios: string = ''; - private _md: string = ''; - private _css: string = ''; - - /** @internal */ - _color: string; +export class Icon extends Ion { + /** @private */ + _iconMode: string; + /** @private */ + _isActive: any; + /** @private */ + _name: string = ''; + /** @private */ + _ios: string = ''; + /** @private */ + _md: string = ''; + /** @private */ + _css: string = ''; /** * @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`. @@ -57,22 +62,27 @@ export class Icon { get color(): string { return this._color; } - set color(value: string) { - this._updateColor(value); + this._setColor('icon', value); } /** - * @private + * @input {string} The mode to apply to this component. */ - mode: string; + @Input() + set mode(val: string) { + this._setMode('icon', val); + } constructor( config: Config, - private _elementRef: ElementRef, - private _renderer: Renderer + elementRef: ElementRef, + renderer: Renderer ) { - this.mode = config.get('iconMode'); + super(config, elementRef, renderer); + + this.mode = config.get('mode'); + this._iconMode = config.get('iconMode'); } /** @@ -80,7 +90,7 @@ export class Icon { */ ngOnDestroy() { if (this._css) { - this._renderer.setElementClass(this._elementRef.nativeElement, this._css, false); + this.setElementClass(this._css, false); } } @@ -96,7 +106,7 @@ export class Icon { if (!(/^md-|^ios-|^logo-/.test(val))) { // this does not have one of the defaults // so lets auto add in the mode prefix for them - val = this.mode + '-' + val; + val = this._iconMode + '-' + val; } this._name = val; this.update(); @@ -142,62 +152,43 @@ export class Icon { this.update(); } + /** + * @private + */ + @HostBinding('class.hide') _hidden: boolean = false; + /** * @private */ update() { let css = 'ion-'; - if (this._ios && this.mode === 'ios') { + this._hidden = (this._name === null); + + if (this._ios && this._iconMode === 'ios') { css += this._ios; - } else if (this._md && this.mode === 'md') { + } else if (this._md && this._iconMode === 'md') { css += this._md; } else { css += this._name; } - if (this.mode === 'ios' && !this.isActive && css.indexOf('logo') < 0) { + if (this._iconMode === 'ios' && !this.isActive && css.indexOf('logo') < 0) { css += '-outline'; } if (this._css !== css) { if (this._css) { - this._renderer.setElementClass(this._elementRef.nativeElement, this._css, false); + this.setElementClass(this._css, false); } this._css = css; - this._renderer.setElementClass(this._elementRef.nativeElement, css, true); + this.setElementClass(css, true); - this._renderer.setElementAttribute(this._elementRef.nativeElement, 'aria-label', + this.setElementAttribute('aria-label', css.replace('ion-', '').replace('ios-', '').replace('md-', '').replace('-', ' ')); } } - /** - * @private - * @param {string} add class name - */ - addClass(className: string) { - this._renderer.setElementClass(this._elementRef.nativeElement, className, true); - } - - /** - * @internal - */ - _updateColor(newColor: string) { - this._setElementColor(this._color, false); - this._setElementColor(newColor, true); - this._color = newColor; - } - - /** - * @internal - */ - _setElementColor(color: string, isAdd: boolean) { - if (color !== null && color !== '') { - this._renderer.setElementClass(this._elementRef.nativeElement, `icon-${color}`, isAdd); - } - } - } diff --git a/src/components/icon/test/basic/main.html b/src/components/icon/test/basic/main.html index 738a7f3aa2..d68e2a5da1 100644 --- a/src/components/icon/test/basic/main.html +++ b/src/components/icon/test/basic/main.html @@ -83,7 +83,7 @@

- diff --git a/src/components/input/input-base.ts b/src/components/input/input-base.ts index 8a9c944e21..61121f9428 100644 --- a/src/components/input/input-base.ts +++ b/src/components/input/input-base.ts @@ -1,54 +1,53 @@ -import { ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core'; +import { ElementRef, Renderer } from '@angular/core'; import { NgControl } from '@angular/forms'; import { App } from '../app/app'; -import { closest, copyInputAttributes, Coordinates, hasPointerMoved, pointerCoord } from '../../util/dom'; +import { copyInputAttributes, PointerCoordinates, hasPointerMoved, pointerCoord } from '../../util/dom'; import { Config } from '../../config/config'; import { Content } from '../content/content'; import { Form } from '../../util/form'; +import { Ion } from '../ion'; import { isTrueProperty } from '../../util/util'; import { Item } from '../item/item'; import { NativeInput, NextInput } from './native-input'; -import { NavController } from '../nav/nav-controller'; -import { NavControllerBase } from '../nav/nav-controller-base'; +import { NavController } from '../../navigation/nav-controller'; +import { NavControllerBase } from '../../navigation/nav-controller-base'; import { Platform } from '../../platform/platform'; -export class InputBase { - protected _coord: Coordinates; - protected _deregScroll: Function; - protected _disabled: boolean = false; - protected _keyboardHeight: number; - protected _scrollMove: EventListener; - protected _type: string = 'text'; - protected _useAssist: boolean; - protected _usePadding: boolean; - protected _value: any = ''; - protected _isTouch: boolean; - protected _autoFocusAssist: string; - protected _autoComplete: string; - protected _autoCorrect: string; - protected _nav: NavControllerBase; +export class InputBase extends Ion { + _coord: PointerCoordinates; + _deregScroll: Function; + _disabled: boolean = false; + _keyboardHeight: number; + _scrollMove: EventListener; + _type: string = 'text'; + _useAssist: boolean; + _usePadding: boolean; + _value: any = ''; + _isTouch: boolean; + _autoFocusAssist: string; + _autoComplete: string; + _autoCorrect: string; + _nav: NavControllerBase; + _native: NativeInput; inputControl: NgControl; - @Input() clearInput: any; - @Input() placeholder: string = ''; - @ViewChild(NativeInput) protected _native: NativeInput; - @Output() blur: EventEmitter = new EventEmitter(); - @Output() focus: EventEmitter = new EventEmitter(); - constructor( config: Config, protected _form: Form, protected _item: Item, protected _app: App, protected _platform: Platform, - protected _elementRef: ElementRef, + elementRef: ElementRef, + renderer: Renderer, protected _scrollView: Content, nav: NavController, ngControl: NgControl ) { + super(config, elementRef, renderer); + this._nav = nav; this._useAssist = config.getBoolean('scrollAssist', false); this._usePadding = config.getBoolean('scrollPadding', this._useAssist); @@ -66,49 +65,27 @@ export class InputBase { _form.register(this); } - ngOnInit() { - if (this._item) { - this._item.setCssClass('item-input', true); - this._item.registerInput(this._type); - } + scrollMove(ev: UIEvent) { + // scroll move event listener this instance can reuse + if (!(this._nav && this._nav.isTransitioning())) { + this.deregScrollMove(); - let clearInput = this.clearInput; - if (typeof clearInput === 'string') { - this.clearInput = (clearInput === '' || clearInput === 'true'); - } - } + if (this.hasFocus()) { + this._native.hideFocus(true); - ngAfterContentInit() { - let self = this; + this._scrollView.onScrollEnd(() => { + this._native.hideFocus(false); - self._scrollMove = function(ev: UIEvent) { - // scroll move event listener this instance can reuse - if (!(self._nav && self._nav.isTransitioning())) { - self.deregScrollMove(); - - if (self.hasFocus()) { - self._native.hideFocus(true); - - self._scrollView.onScrollEnd(function() { - self._native.hideFocus(false); - - if (self.hasFocus()) { - // if it still has focus then keep listening - self.regScrollMove(); - } - }); - } + if (this.hasFocus()) { + // if it still has focus then keep listening + this.regScrollMove(); + } + }); } - }; + } + }; - this.setItemInputControlCss(); - } - - ngAfterContentChecked() { - this.setItemInputControlCss(); - } - - private setItemInputControlCss() { + setItemInputControlCss() { let item = this._item; let nativeInput = this._native; let inputControl = this.inputControl; @@ -124,35 +101,21 @@ export class InputBase { } } - private setControlCss(element: any, control: any) { - element.setCssClass('ng-untouched', control.untouched); - element.setCssClass('ng-touched', control.touched); - element.setCssClass('ng-pristine', control.pristine); - element.setCssClass('ng-dirty', control.dirty); - element.setCssClass('ng-valid', control.valid); - element.setCssClass('ng-invalid', !control.valid); + setControlCss(element: any, control: NgControl) { + element.setElementClass('ng-untouched', control.untouched); + element.setElementClass('ng-touched', control.touched); + element.setElementClass('ng-pristine', control.pristine); + element.setElementClass('ng-dirty', control.dirty); + element.setElementClass('ng-valid', control.valid); + element.setElementClass('ng-invalid', !control.valid); } - ngOnDestroy() { - this._form.deregister(this); - } - - @Input() - get value() { - return this._value; - } - - set value(val: any) { + setValue(val: any) { this._value = val; this.checkHasValue(val); } - @Input() - get type() { - return this._type; - } - - set type(val) { + setType(val: string) { this._type = 'text'; if (val) { @@ -164,22 +127,16 @@ export class InputBase { } } - @Input() - get disabled() { - return this._disabled; - } - - set disabled(val) { + setDisabled(val: boolean) { this._disabled = isTrueProperty(val); - this._item && this._item.setCssClass('item-input-disabled', this._disabled); + this._item && this._item.setElementClass('item-input-disabled', this._disabled); this._native && this._native.isDisabled(this._disabled); } /** * @private */ - @ViewChild(NativeInput) - private set _nativeInput(nativeInput: NativeInput) { + setNativeInput(nativeInput: NativeInput) { this._native = nativeInput; if (this._item && this._item.labelId !== null) { @@ -200,7 +157,7 @@ export class InputBase { }); this.checkHasValue(nativeInput.getValue()); - this.disabled = this._disabled; + this.setDisabled(this._disabled); var ionInputEle: HTMLElement = this._elementRef.nativeElement; let nativeInputEle: HTMLElement = nativeInput.element(); @@ -245,8 +202,7 @@ export class InputBase { /** * @private */ - @ViewChild(NextInput) - private set _nextInput(nextInput: NextInput) { + setNextInput(nextInput: NextInput) { if (nextInput) { nextInput.focused.subscribe(() => { this._form.tabFocus(this); @@ -290,7 +246,7 @@ export class InputBase { */ checkHasValue(inputValue: any) { if (this._item) { - this._item.setCssClass('input-has-value', !!(inputValue && inputValue !== '')); + this._item.setElementClass('input-has-value', !!(inputValue && inputValue !== '')); } } @@ -299,14 +255,14 @@ export class InputBase { */ focusChange(inputHasFocus: boolean) { if (this._item) { - this._item.setCssClass('input-has-focus', inputHasFocus); + this._item.setElementClass('input-has-focus', inputHasFocus); } if (!inputHasFocus) { this.deregScrollMove(); } } - private pointerStart(ev: any) { + pointerStart(ev: any) { // input cover touchstart console.debug('scroll assist pointerStart', ev.type); @@ -320,7 +276,7 @@ export class InputBase { } } - private pointerEnd(ev: any) { + pointerEnd(ev: any) { // input cover touchend/mouseup console.debug('scroll assist pointerEnd', ev.type); @@ -362,8 +318,8 @@ export class InputBase { // find out if text input should be manually scrolled into view // get container of this input, probably an ion-item a few nodes up - var ele = this._elementRef.nativeElement; - ele = closest(ele, 'ion-item,[ion-item]') || ele; + var ele: HTMLElement = this._elementRef.nativeElement; + ele = ele.closest('ion-item,[ion-item]') || ele; var scrollData = InputBase.getScrollData(ele.offsetTop, ele.offsetHeight, scrollView.getContentDimensions(), this._keyboardHeight, this._platform.height()); if (scrollData.scrollAmount > -3 && scrollData.scrollAmount < 3) { @@ -419,7 +375,7 @@ export class InputBase { /** * @private */ - private setFocus() { + setFocus() { // immediately set focus this._form.setAsFocused(this); @@ -450,12 +406,12 @@ export class InputBase { /** * @private */ - private regScrollMove() { + regScrollMove() { // register scroll move listener if (this._useAssist && this._scrollView) { setTimeout(() => { this.deregScrollMove(); - this._deregScroll = this._scrollView.addScrollListener(this._scrollMove); + this._deregScroll = this._scrollView.addScrollListener(this.scrollMove.bind(this)); }, 80); } } @@ -463,7 +419,7 @@ export class InputBase { /** * @private */ - private deregScrollMove() { + deregScrollMove() { // deregister the scroll move listener this._deregScroll && this._deregScroll(); } diff --git a/src/components/input/input.ts b/src/components/input/input.ts index 3102f10b38..12356179cd 100644 --- a/src/components/input/input.ts +++ b/src/components/input/input.ts @@ -1,16 +1,15 @@ -import { Component, Optional, ElementRef, ViewChild, ViewEncapsulation } from '@angular/core'; -import { NgIf } from '@angular/common'; -import { NgControl, NgModel } from '@angular/forms'; +import { Component, Optional, ElementRef, EventEmitter, Input, Output, Renderer, ViewChild, ViewEncapsulation } from '@angular/core'; +import { NgControl } from '@angular/forms'; import { App } from '../app/app'; import { Config } from '../../config/config'; import { Content } from '../content/content'; import { Form } from '../../util/form'; import { InputBase } from './input-base'; +import { isTrueProperty } from '../../util/util'; import { Item } from '../item/item'; -import { Label } from '../label/label'; import { NativeInput, NextInput } from './native-input'; -import { NavController } from '../nav/nav-controller'; +import { NavController } from '../../navigation/nav-controller'; import { Platform } from '../../platform/platform'; @@ -75,16 +74,15 @@ import { Platform } from '../../platform/platform'; */ @Component({ selector: 'ion-input', - template: ` - - - -

- `, - directives: [NativeInput, NextInput, NgIf, NgModel], + template: + '' + + '' + + '' + + '
', encapsulation: ViewEncapsulation.None, }) export class TextInput extends InputBase { + constructor( config: Config, form: Form, @@ -92,13 +90,104 @@ export class TextInput extends InputBase { app: App, platform: Platform, elementRef: ElementRef, + renderer: Renderer, @Optional() scrollView: Content, @Optional() nav: NavController, @Optional() ngControl: NgControl ) { - super(config, form, item, app, platform, elementRef, scrollView, nav, ngControl); + super(config, form, item, app, platform, elementRef, renderer, scrollView, nav, ngControl); + + this.mode = config.get('mode'); } + /** + * @private + */ + _clearInput: boolean = false; + + /** + * @private + */ + @Input() placeholder: string = ''; + + /** + * @private + */ + @Input() + get clearInput() { + return this._clearInput; + } + set clearInput(val: any) { + this._clearInput = isTrueProperty(val); + } + + /** + * @private + */ + @Input() + get value() { + return this._value; + } + set value(val: any) { + super.setValue(val); + } + + /** + * @private + */ + @Input() + get type() { + return this._type; + } + set type(val: any) { + super.setType(val); + } + + /** + * @private + */ + @Input() + get disabled() { + return this._disabled; + } + set disabled(val: any) { + super.setDisabled(val); + } + + /** + * @input {string} The mode to apply to this component. + */ + @Input() + set mode(val: string) { + this._setMode('input', val); + } + + /** + * @private + */ + @ViewChild(NativeInput) + set _nativeInput(nativeInput: NativeInput) { + super.setNativeInput(nativeInput); + } + + /** + * @private + */ + @ViewChild(NextInput) + set _nextInput(nextInput: NextInput) { + super.setNextInput(nextInput); + } + + /** + * @private + */ + @Output() blur: EventEmitter = new EventEmitter(); + + /** + * @private + */ + @Output() focus: EventEmitter = new EventEmitter(); + /** * @private */ @@ -112,6 +201,29 @@ export class TextInput extends InputBase { inputFocused(ev: UIEvent) { this.focus.emit(ev); } + /** + * @private + */ + ngOnInit() { + if (this._item) { + this._item.setElementClass('item-input', true); + this._item.registerInput(this._type); + } + } + + /** + * @private + */ + ngAfterContentChecked() { + this.setItemInputControlCss(); + } + + /** + * @private + */ + ngOnDestroy() { + this._form.deregister(this); + } /** * @private @@ -171,10 +283,9 @@ export class TextInput extends InputBase { @Component({ selector: 'ion-textarea', template: - '' + + '' + '' + '
', - directives: [NativeInput, NextInput, NgIf], encapsulation: ViewEncapsulation.None, }) export class TextArea extends InputBase { @@ -185,23 +296,113 @@ export class TextArea extends InputBase { app: App, platform: Platform, elementRef: ElementRef, + renderer: Renderer, @Optional() scrollView: Content, @Optional() nav: NavController, @Optional() ngControl: NgControl ) { - super(config, form, item, app, platform, elementRef, scrollView, nav, ngControl); + super(config, form, item, app, platform, elementRef, renderer, scrollView, nav, ngControl); + + this.mode = config.get('mode'); } + /** + * @private + */ + @Input() placeholder: string = ''; + + /** + * @private + */ + @Input() + get value() { + return this._value; + } + set value(val: any) { + super.setValue(val); + } + + /** + * @private + */ + @Input() + get type() { + return this._type; + } + set type(val: any) { + super.setType(val); + } + + /** + * @private + */ + @Input() + get disabled() { + return this._disabled; + } + set disabled(val: any) { + super.setDisabled(val); + } + + /** + * @input {string} The mode to apply to this component. + */ + @Input() + set mode(val: string) { + this._setMode('input', val); + } + + /** + * @private + */ + @ViewChild(NativeInput) + set _nativeInput(nativeInput: NativeInput) { + super.setNativeInput(nativeInput); + } + + /** + * @private + */ + @ViewChild(NextInput) + set _nextInput(nextInput: NextInput) { + super.setNextInput(nextInput); + } + + /** + * @private + */ + @Output() blur: EventEmitter = new EventEmitter(); + + /** + * @private + */ + @Output() focus: EventEmitter = new EventEmitter(); + /** * @private */ ngOnInit() { - super.ngOnInit(); if (this._item) { - this._item.setCssClass('item-textarea', true); + this._item.setElementClass('item-textarea', true); + this._item.setElementClass('item-input', true); + this._item.registerInput(this._type); } } + /** + * @private + */ + ngAfterContentChecked() { + this.setItemInputControlCss(); + } + + /** + * @private + */ + ngOnDestroy() { + this._form.deregister(this); + } + /** * @private */ diff --git a/src/components/input/native-input.ts b/src/components/input/native-input.ts index 8493c72656..3d8c70db45 100644 --- a/src/components/input/native-input.ts +++ b/src/components/input/native-input.ts @@ -12,17 +12,17 @@ import { CSS, hasFocus } from '../../util/dom'; selector: '.text-input' }) export class NativeInput { - private _relocated: boolean; - private _clone: boolean; - private _blurring: boolean; - private _unrefBlur: Function; + _relocated: boolean; + _clone: boolean; + _blurring: boolean; + _unrefBlur: Function; @Output() focusChange: EventEmitter = new EventEmitter(); @Output() valueChange: EventEmitter = new EventEmitter(); constructor( - private _elementRef: ElementRef, - private _renderer: Renderer, + public _elementRef: ElementRef, + public _renderer: Renderer, config: Config, public ngControl: NgControl ) { @@ -31,12 +31,12 @@ export class NativeInput { } @HostListener('input', ['$event']) - private _change(ev: any) { + _change(ev: any) { this.valueChange.emit(ev.target.value); } @HostListener('focus') - private _focus() { + _focus() { var self = this; self.focusChange.emit(true); @@ -65,7 +65,7 @@ export class NativeInput { } @HostListener('blur') - private _blur() { + _blur() { this.focusChange.emit(false); this.hideFocus(false); @@ -111,7 +111,7 @@ export class NativeInput { // move the native input to a location safe to receive focus // according to the browser, the native input receives focus in an // area which doesn't require the browser to scroll the input into place - focusedInputEle.style[CSS.transform] = `translate3d(-9999px,${inputRelativeY}px,0)`; + (focusedInputEle.style)[CSS.transform] = `translate3d(-9999px,${inputRelativeY}px,0)`; focusedInputEle.style.opacity = '0'; } @@ -129,7 +129,7 @@ export class NativeInput { if (this._clone) { // should remove the cloned node focusedInputEle.classList.remove('cloned-active'); - focusedInputEle.style[CSS.transform] = ''; + (focusedInputEle.style)[CSS.transform] = ''; focusedInputEle.style.opacity = ''; removeClone(focusedInputEle, 'cloned-focus'); } @@ -164,7 +164,7 @@ export class NativeInput { return this.element().value; } - setCssClass(cssClass: string, shouldAdd: boolean) { + setElementClass(cssClass: string, shouldAdd: boolean) { this._renderer.setElementClass(this._elementRef.nativeElement, cssClass, shouldAdd); } diff --git a/src/components/item/item.ts b/src/components/item/item.ts index 74750d6048..a46c1d54cf 100644 --- a/src/components/item/item.ts +++ b/src/components/item/item.ts @@ -1,10 +1,10 @@ -import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, Directive, ElementRef, forwardRef, Input, Renderer, ViewChild, ViewEncapsulation } from '@angular/core'; -import { NgIf } from '@angular/common'; +import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, Directive, ElementRef, Input, QueryList, Renderer, ViewChild, ViewEncapsulation } from '@angular/core'; import { Button } from '../button/button'; +import { Config } from '../../config/config'; import { Form } from '../../util/form'; import { Icon } from '../icon/icon'; -import { Reorder } from '../item/item-reorder'; +import { Ion } from '../ion'; import { Label } from '../label/label'; @@ -272,30 +272,31 @@ import { Label } from '../label/label'; */ @Component({ selector: 'ion-list-header,ion-item,[ion-item],ion-item-divider', - template: ` - -
-
- - - - - -
- - -
- - `, - directives: [NgIf, Label, forwardRef(() => Reorder)], + template: + '' + + '
' + + '
' + + '' + + '' + + '' + + '' + + '' + + '
' + + '' + + '' + + '
' + + '
', + host: { + 'class': 'item' + }, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, }) -export class Item { - private _ids: number = -1; - private _inputs: Array = []; - private _label: Label; - private _viewLabel: boolean = true; +export class Item extends Ion { + _ids: number = -1; + _inputs: Array = []; + _label: Label; + _viewLabel: boolean = true; /** * @private @@ -307,22 +308,26 @@ export class Item { */ labelId: string = null; - /** @internal */ - _color: string; - /** * @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`. */ @Input() - get color(): string { - return this._color; + set color(val: string) { + this._updateColor(val); } - set color(value: string) { - this._updateColor(value); + /** + * @input {string} The mode to apply to this component. + */ + @Input() + set mode(val: string) { + this._setMode('item', val); } - constructor(form: Form, private _renderer: Renderer, private _elementRef: ElementRef) { + constructor(form: Form, config: Config, elementRef: ElementRef, renderer: Renderer) { + super(config, elementRef, renderer); + + this.mode = config.get('mode'); this.id = form.nextId().toString(); } @@ -344,10 +349,15 @@ export class Item { } if (this._inputs.length > 1) { - this.setCssClass('item-multiple-inputs', true); + this.setElementClass('item-multiple-inputs', true); } } + _updateColor(newColor: string, colorClass?: string) { + colorClass = colorClass || 'item'; // item-radio + this._setColor(colorClass, newColor); + } + /** * @private */ @@ -359,12 +369,12 @@ export class Item { * @private */ @ContentChild(Label) - private set contentLabel(label: Label) { + set contentLabel(label: Label) { if (label) { this._label = label; this.labelId = label.id = ('lbl-' + this.id); if (label.type) { - this.setCssClass('item-label-' + label.type, true); + this.setElementClass('item-label-' + label.type, true); } this._viewLabel = false; } @@ -374,7 +384,7 @@ export class Item { * @private */ @ViewChild(Label) - private set viewLabel(label: Label) { + set viewLabel(label: Label) { if (!this._label) { this._label = label; } @@ -384,12 +394,10 @@ export class Item { * @private */ @ContentChildren(Button) - private set _buttons(buttons: any) { - buttons.toArray().forEach((button: any) => { - // Don't add the item-button class if the user specifies - // a different size button - if (!button.isItem && !button._size) { - button.addClass('item-button'); + set _buttons(buttons: QueryList - - - -
- -
- `, - directives: [BackButton, BackButtonText, Icon, ToolbarBackground], + template: + '
' + + '' + + '' + + '' + + '' + + '
' + + '' + + '
', host: { '[hidden]': '_hidden', 'class': 'toolbar', @@ -122,29 +67,42 @@ class ToolbarBackground { } }) export class Navbar extends ToolbarBase { - private _bbIcon: string; - private _bbText: string; - private _hidden: boolean = false; - private _hideBb: boolean = false; - private _bbRef: ElementRef; - private _bbtRef: ElementRef; - private _bgRef: ElementRef; - private _sbPadding: boolean; - - /** @internal */ - _color: string; + /** + * @private + */ + @ViewChild('bbTxt') _bbTxt: ElementRef; + /** + * @private + */ + _bbIcon: string; + /** + * @private + */ + _hidden: boolean = false; + /** + * @private + */ + _hideBb: boolean = false; + /** + * @private + */ + _sbPadding: boolean; /** * @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`. */ @Input() - get color(): string { - return this._color; + set color(val: string) { + this._setColor('toolbar', val); } - set color(value: string) { - this._updateColor(value); - } + /** + * @input {string} The mode to apply to this component. + */ + @Input() + set mode(val: string) { + this._setMode('toolbar', val); + } /** * @input {boolean} whether the back button should be shown or not @@ -158,68 +116,39 @@ export class Navbar extends ToolbarBase { } constructor( - private _app: App, + public _app: App, @Optional() viewCtrl: ViewController, - private _elementRef: ElementRef, - private _renderer: Renderer, - config: Config + @Optional() private navCtrl: NavController, + config: Config, + elementRef: ElementRef, + renderer: Renderer ) { - super(_elementRef); + super(config, elementRef, renderer); - viewCtrl && viewCtrl.setNavbar(this); + this.mode = config.get('mode'); + + viewCtrl && viewCtrl._setNavbar(this); this._bbIcon = config.get('backButtonIcon'); - this._bbText = config.get('backButtonText'); - this._sbPadding = config.getBoolean('statusbarPadding', false); + this._sbPadding = config.getBoolean('statusbarPadding'); + } + + ngAfterViewInit() { + this.setBackButtonText(this._config.get('backButtonText', 'Back')); + } + + backButtonClick(ev: UIEvent) { + ev.preventDefault(); + ev.stopPropagation(); + + this.navCtrl && this.navCtrl.pop(null, null); } /** - * @private + * Set the text of the Back Button in the Nav Bar. Defaults to "Back". */ setBackButtonText(text: string) { - this._bbText = text; - } - - /** - * @private - */ - getBackButtonRef() { - return this._bbRef; - } - - /** - * @private - */ - setBackButtonRef(backButtonElementRef: ElementRef) { - this._bbRef = backButtonElementRef; - } - - /** - * @private - */ - getBackButtonTextRef() { - return this._bbtRef; - } - - /** - * @private - */ - setBackButtonTextRef(backButtonTextElementRef: ElementRef) { - this._bbtRef = backButtonTextElementRef; - } - - /** - * @private - */ - setBackgroundRef(backgrouneElementRef: ElementRef) { - this._bgRef = backgrouneElementRef; - } - - /** - * @private - */ - getBackgroundRef() { - return this._bgRef; + this._renderer.setText(this._bbTxt.nativeElement, text); } /** @@ -241,41 +170,4 @@ export class Navbar extends ToolbarBase { this._hidden = isHidden; } - /** - * @internal - */ - _updateColor(newColor: string) { - this._setElementColor(this._color, false); - this._setElementColor(newColor, true); - this._color = newColor; - } - - /** - * @internal - */ - _setElementColor(color: string, isAdd: boolean) { - if (color !== null && color !== '') { - this._renderer.setElementClass(this._elementRef.nativeElement, `toolbar-${color}`, isAdd); - } - } - -} - - -/** - * @private -*/ -@Directive({ - selector: 'template[navbar]' -}) -export class NavbarTemplate { - constructor() { - // deprecated warning: added 2016-06-14, beta.10 - console.warn('ion-navbar no longer requires *navbar attribute. Please restructure header to:\n' + - '\n' + - ' \n' + - ' ...\n' + - ' \n' + - ''); - } } diff --git a/src/components/radio/radio-button.ts b/src/components/radio/radio-button.ts index 061de7b34a..2db6e0c142 100644 --- a/src/components/radio/radio-button.ts +++ b/src/components/radio/radio-button.ts @@ -1,6 +1,8 @@ import { Component, ElementRef, EventEmitter, HostListener, Input, OnInit, OnDestroy, Optional, Output, Renderer, ViewEncapsulation } from '@angular/core'; +import { Config } from '../../config/config'; import { Form } from '../../util/form'; +import { Ion } from '../ion'; import { isBlank, isCheckedProperty, isPresent, isTrueProperty } from '../../util/util'; import { Item } from '../item/item'; import { RadioGroup } from './radio-group'; @@ -43,49 +45,70 @@ import { RadioGroup } from './radio-group'; */ @Component({ selector: 'ion-radio', - template: ` -
-
-
- - `, + template: + '
' + + '
' + + '
' + + '', host: { '[class.radio-disabled]': '_disabled' }, encapsulation: ViewEncapsulation.None, }) -export class RadioButton implements OnDestroy, OnInit { - private _checked: boolean = false; - private _disabled: boolean = false; - private _labelId: string; - private _value: any = null; +export class RadioButton extends Ion implements OnDestroy, OnInit { /** - * @private + * @internal + */ + _checked: boolean = false; + + /** + * @internal + */ + _disabled: boolean = false; + + /** + * @internal + */ + _labelId: string; + + /** + * @internal + */ + _value: any = null; + + /** + * @internal */ id: string; - /** @internal */ - _color: string; - /** * @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`. */ @Input() - get color(): string { - return this._color; + set color(val: string) { + this._setColor('radio', val); + + if (this._item) { + this._item._updateColor(val, 'item-radio'); + } } - set color(value: string) { - this._updateColor(value); - } + /** + * @input {string} The mode to apply to this component. + */ + @Input() + set mode(val: string) { + this._setMode('radio', val); + } /** * @output {any} expression to be evaluated when selected @@ -94,11 +117,15 @@ export class RadioButton implements OnDestroy, OnInit { constructor( private _form: Form, - private _elementRef: ElementRef, - private _renderer: Renderer, + config: Config, + elementRef: ElementRef, + renderer: Renderer, @Optional() private _item: Item, @Optional() private _group: RadioGroup ) { + super(config, elementRef, renderer); + + this.mode = config.get('mode'); _form.register(this); if (_group) { @@ -111,7 +138,7 @@ export class RadioButton implements OnDestroy, OnInit { // reset to the item's id instead of the radiogroup id this.id = 'rb-' + _item.registerInput('radio'); this._labelId = 'lbl-' + _item.id; - this._item.setCssClass('item-radio', true); + this._item.setElementClass('item-radio', true); } } @@ -123,7 +150,6 @@ export class RadioButton implements OnDestroy, OnInit { // if the value is not defined then use it's unique id return isBlank(this._value) ? this.id : this._value; } - set value(val: any) { this._value = val; } @@ -140,7 +166,7 @@ export class RadioButton implements OnDestroy, OnInit { this._checked = isTrueProperty(isChecked); if (this._item) { - this._item.setCssClass('item-radio-checked', this._checked); + this._item.setElementClass('item-radio-checked', this._checked); } } @@ -151,17 +177,16 @@ export class RadioButton implements OnDestroy, OnInit { get disabled(): boolean { return this._disabled; } - set disabled(val: boolean) { this._disabled = isTrueProperty(val); - this._item && this._item.setCssClass('item-radio-disabled', this._disabled); + this._item && this._item.setElementClass('item-radio-disabled', this._disabled); } /** - * @private + * @internal */ @HostListener('click', ['$event']) - private _click(ev: UIEvent) { + _click(ev: UIEvent) { console.debug('radio, select', this.id); ev.preventDefault(); ev.stopPropagation(); @@ -171,7 +196,7 @@ export class RadioButton implements OnDestroy, OnInit { } /** - * @private + * @internal */ ngOnInit() { if (this._group && isPresent(this._group.value)) { @@ -180,32 +205,10 @@ export class RadioButton implements OnDestroy, OnInit { } /** - * @private + * @internal */ ngOnDestroy() { this._form.deregister(this); this._group && this._group.remove(this); } - - /** - * @internal - */ - _updateColor(newColor: string) { - this._setElementColor(this._color, false); - this._setElementColor(newColor, true); - this._color = newColor; - } - - /** - * @internal - */ - _setElementColor(color: string, isAdd: boolean) { - if (color !== null && color !== '') { - this._renderer.setElementClass(this._elementRef.nativeElement, `radio-${color}`, isAdd); - - if (this._item) { - this._item._updateColor(color, 'item-radio'); - } - } - } } diff --git a/src/components/range/range.ts b/src/components/range/range.ts index 9d314bc608..7e48c42b48 100644 --- a/src/components/range/range.ts +++ b/src/components/range/range.ts @@ -1,35 +1,34 @@ -import { AfterViewInit, Component, ElementRef, EventEmitter, forwardRef, Input, Inject, OnDestroy, OnInit, Optional, Output, Provider, QueryList, Renderer, ViewChild, ViewChildren, ViewEncapsulation } from '@angular/core'; -import { NgFor, NgIf } from '@angular/common'; +import { AfterViewInit, Component, ElementRef, EventEmitter, forwardRef, Input, Inject, OnDestroy, OnInit, Optional, Output, QueryList, Renderer, ViewChild, ViewChildren, ViewEncapsulation } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { clamp, isNumber, isPresent, isString, isTrueProperty } from '../../util/util'; -import { Coordinates, pointerCoord, raf } from '../../util/dom'; +import { Config } from '../../config/config'; import { Debouncer } from '../../util/debouncer'; import { Form } from '../../util/form'; +import { Ion } from '../ion'; import { Item } from '../item/item'; +import { PointerCoordinates, pointerCoord, raf } from '../../util/dom'; import { UIEventManager } from '../../util/ui-event-manager'; - -export const RANGE_VALUE_ACCESSOR = new Provider( - NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => Range), multi: true}); +export const RANGE_VALUE_ACCESSOR: any = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => Range), + multi: true +}; /** * @private */ @Component({ selector: '.range-knob-handle', - template: ` -
{{_val}}
-
- `, - directives: [NgIf], + template: + '
{{_val}}
' + + '
', host: { '[class.range-knob-pressed]': 'pressed', '[class.range-knob-min]': '_val===range.min', '[class.range-knob-max]': '_val===range.max', '[style.left]': '_x', - '[style.top]': '_y', - '[style.transform]': '_trns', '[attr.aria-valuenow]': '_val', '[attr.aria-valuemin]': 'range.min', '[attr.aria-valuemax]': 'range.max', @@ -38,14 +37,14 @@ export const RANGE_VALUE_ACCESSOR = new Provider( } }) export class RangeKnob implements OnInit { - private _ratio: number; - private _val: number; - private _x: string; + _ratio: number; + _val: number; + _x: string; pressed: boolean; @Input() upper: boolean; - constructor(@Inject(forwardRef(() => Range)) private range: Range) {} + constructor(@Inject(forwardRef(() => Range)) public range: Range) {} get ratio(): number { return this._ratio; @@ -179,18 +178,16 @@ export class RangeKnob implements OnInit { */ @Component({ selector: 'ion-range', - template: ` - -
-
-
-
-
-
-
- - `, - directives: [NgFor, NgIf, RangeKnob], + template: + '' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '', host: { '[class.range-disabled]': '_disabled', '[class.range-pressed]': '_pressed', @@ -199,52 +196,52 @@ export class RangeKnob implements OnInit { providers: [RANGE_VALUE_ACCESSOR], encapsulation: ViewEncapsulation.None, }) -export class Range implements AfterViewInit, ControlValueAccessor, OnDestroy { - private _dual: boolean = false; - private _pin: boolean; - private _disabled: boolean = false; - private _pressed: boolean; - private _labelId: string; - private _fn: Function; +export class Range extends Ion implements AfterViewInit, ControlValueAccessor, OnDestroy { + _dual: boolean = false; + _pin: boolean; + _disabled: boolean = false; + _pressed: boolean; + _labelId: string; + _fn: Function; - private _active: RangeKnob; - private _start: Coordinates = null; - private _rect: ClientRect; - private _ticks: any[] = []; - private _barL: string; - private _barR: string; + _active: RangeKnob; + _start: PointerCoordinates = null; + _rect: ClientRect; + _ticks: any[]; + _barL: string; + _barR: string; - private _min: number = 0; - private _max: number = 100; - private _step: number = 1; - private _snaps: boolean = false; + _min: number = 0; + _max: number = 100; + _step: number = 1; + _snaps: boolean = false; - private _debouncer: Debouncer = new Debouncer(0); - private _events: UIEventManager = new UIEventManager(); + _debouncer: Debouncer = new Debouncer(0); + _events: UIEventManager = new UIEventManager(); /** * @private */ value: any; - - /** @internal */ - _color: string; - /** * @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`. */ @Input() - get color(): string { - return this._color; + set color(val: string) { + this._setColor('range', val); } - set color(value: string) { - this._updateColor(value); + /** + * @input {string} The mode to apply to this component. + */ + @Input() + set mode(val: string) { + this._setMode('range', val); } - @ViewChild('bar') private _bar: ElementRef; - @ViewChild('slider') private _slider: ElementRef; - @ViewChildren(RangeKnob) private _knobs: QueryList; + @ViewChild('bar') public _bar: ElementRef; + @ViewChild('slider') public _slider: ElementRef; + @ViewChildren(RangeKnob) public _knobs: QueryList; /** * @private @@ -347,15 +344,19 @@ export class Range implements AfterViewInit, ControlValueAccessor, OnDestroy { constructor( private _form: Form, @Optional() private _item: Item, - private _elementRef: ElementRef, - private _renderer: Renderer + config: Config, + elementRef: ElementRef, + renderer: Renderer ) { + super(config, elementRef, renderer); + + this.mode = config.get('mode'); _form.register(this); if (_item) { this.id = 'rng-' + _item.registerInput('range'); this._labelId = 'lbl-' + _item.id; - _item.setCssClass('item-range', true); + _item.setElementClass('item-range', true); } } @@ -480,7 +481,7 @@ export class Range implements AfterViewInit, ControlValueAccessor, OnDestroy { /** * @private */ - setActiveKnob(current: Coordinates, rect: ClientRect) { + setActiveKnob(current: PointerCoordinates, rect: ClientRect) { // figure out which knob is the closest one to the pointer let ratio = (current.x - rect.left) / (rect.width); @@ -495,7 +496,7 @@ export class Range implements AfterViewInit, ControlValueAccessor, OnDestroy { /** * @private */ - updateKnob(current: Coordinates, rect: ClientRect) { + updateKnob(current: PointerCoordinates, rect: ClientRect) { // figure out where the pointer is currently at // update the knob being interacted with if (this._active) { @@ -568,7 +569,7 @@ export class Range implements AfterViewInit, ControlValueAccessor, OnDestroy { * @private */ updateTicks() { - if (this._snaps) { + if (this._snaps && this._ticks) { let ratio = this.ratio; if (this._dual) { let upperRatio = this.ratioUpper; @@ -601,24 +602,6 @@ export class Range implements AfterViewInit, ControlValueAccessor, OnDestroy { return (value - this._min) / (this._max - this._min); } - /** - * @internal - */ - _updateColor(newColor: string) { - this._setElementColor(this._color, false); - this._setElementColor(newColor, true); - this._color = newColor; - } - - /** - * @internal - */ - _setElementColor(color: string, isAdd: boolean) { - if (color !== null && color !== '') { - this._renderer.setElementClass(this._elementRef.nativeElement, `range-${color}`, isAdd); - } - } - /** * @private */ @@ -667,7 +650,7 @@ export class Range implements AfterViewInit, ControlValueAccessor, OnDestroy { } set disabled(val: boolean) { this._disabled = isTrueProperty(val); - this._item && this._item.setCssClass('item-range-disabled', this._disabled); + this._item && this._item.setElementClass('item-range-disabled', this._disabled); } /** diff --git a/src/components/searchbar/searchbar.ts b/src/components/searchbar/searchbar.ts index 86b28f74a6..3c1fac8f00 100644 --- a/src/components/searchbar/searchbar.ts +++ b/src/components/searchbar/searchbar.ts @@ -1,8 +1,8 @@ -import { Component, Directive, ElementRef, EventEmitter, HostBinding, Input, Optional, Output, Renderer, ViewChild, ViewEncapsulation } from '@angular/core'; -import { NgControl, NgModel } from '@angular/forms'; +import { Component, ElementRef, EventEmitter, HostBinding, Input, Optional, Output, Renderer, ViewChild, ViewEncapsulation } from '@angular/core'; +import { NgControl } from '@angular/forms'; import { Config } from '../../config/config'; -import { Icon } from '../icon/icon'; +import { Ion } from '../ion'; import { isPresent } from '../../util/util'; import { Debouncer } from '../../util/debouncer'; @@ -38,7 +38,6 @@ import { Debouncer } from '../../util/debouncer'; '' + '' + '', - directives: [Icon, NgModel], host: { '[class.searchbar-has-value]': '_value', '[class.searchbar-active]': '_isActive', @@ -47,26 +46,27 @@ import { Debouncer } from '../../util/debouncer'; }, encapsulation: ViewEncapsulation.None }) -export class Searchbar { - private _value: string|number = ''; - private _shouldBlur: boolean = true; - private _isActive: boolean = false; - private _searchbarInput: ElementRef; - private _debouncer: Debouncer = new Debouncer(250); - - /** @internal */ - _color: string; +export class Searchbar extends Ion { + _value: string|number = ''; + _shouldBlur: boolean = true; + _isActive: boolean = false; + _searchbarInput: ElementRef; + _debouncer: Debouncer = new Debouncer(250); /** * @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`. */ @Input() - get color(): string { - return this._color; + set color(val: string) { + this._setColor('searchbar', val); } - set color(value: string) { - this._updateColor(value); + /** + * @input {string} The mode to apply to this component. + */ + @Input() + set mode(val: string) { + this._setMode('searchbar', val); } /** @@ -146,11 +146,15 @@ export class Searchbar { @HostBinding('class.searchbar-has-focus') _sbHasFocus: boolean; constructor( - private _elementRef: ElementRef, - private _config: Config, - private _renderer: Renderer, + config: Config, + elementRef: ElementRef, + renderer: Renderer, @Optional() ngControl: NgControl ) { + super(config, elementRef, renderer); + + this.mode = config.get('mode'); + // If the user passed a ngControl we need to set the valueAccessor if (ngControl) { ngControl.valueAccessor = this; @@ -161,7 +165,7 @@ export class Searchbar { * @private */ @ViewChild('searchbarInput') - private set searchbarInput(searchbarInput: ElementRef) { + set searchbarInput(searchbarInput: ElementRef) { this._searchbarInput = searchbarInput; let inputEle = searchbarInput.nativeElement; @@ -211,9 +215,9 @@ export class Searchbar { /** * @private - * After View Initialization position the elements + * After View Checked position the elements */ - ngAfterViewInit() { + ngAfterViewChecked() { this.positionElements(); } @@ -361,24 +365,6 @@ export class Searchbar { this._isActive = false; } - /** - * @internal - */ - _updateColor(newColor: string) { - this._setElementColor(this._color, false); - this._setElementColor(newColor, true); - this._color = newColor; - } - - /** - * @internal - */ - _setElementColor(color: string, isAdd: boolean) { - if (color !== null && color !== '') { - this._renderer.setElementClass(this._elementRef.nativeElement, `searchbar-${color}`, isAdd); - } - } - /** * @private * Write a new value to the element. diff --git a/src/components/segment/segment.ts b/src/components/segment/segment.ts index 690753cf02..e1dcf513b0 100644 --- a/src/components/segment/segment.ts +++ b/src/components/segment/segment.ts @@ -1,6 +1,8 @@ import { Component, ContentChildren, Directive, ElementRef, EventEmitter, HostListener, Input, Output, Optional, QueryList, Renderer, ViewEncapsulation } from '@angular/core'; import { NgControl } from '@angular/forms'; +import { Config } from '../../config/config'; +import { Ion } from '../ion'; import { isPresent, isTrueProperty } from '../../util/util'; @@ -42,10 +44,9 @@ import { isPresent, isTrueProperty } from '../../util/util'; */ @Component({ selector: 'ion-segment-button', - template: ` - - - `, + template: + '' + + '
', host: { 'tappable': '', 'class': 'segment-button', @@ -54,7 +55,7 @@ import { isPresent, isTrueProperty } from '../../util/util'; encapsulation: ViewEncapsulation.None, }) export class SegmentButton { - private _disabled: boolean = false; + _disabled: boolean = false; /** * @input {string} the value of the segment button. Required. @@ -78,13 +79,13 @@ export class SegmentButton { set disabled(val: boolean) { this._disabled = isTrueProperty(val); - this.setCssClass('segment-button-disabled', this._disabled); + this._setCssClass('segment-button-disabled', this._disabled); } /** * @private */ - setCssClass(cssClass: string, shouldAdd: boolean) { + _setCssClass(cssClass: string, shouldAdd: boolean) { this._renderer.setElementClass(this._elementRef.nativeElement, cssClass, shouldAdd); } @@ -93,7 +94,7 @@ export class SegmentButton { * On click of a SegmentButton */ @HostListener('click') - private onClick() { + onClick() { console.debug('SegmentButton, select', this.value); this.ionSelect.emit(this); } @@ -177,27 +178,27 @@ export class SegmentButton { @Directive({ selector: 'ion-segment' }) -export class Segment { - private _disabled: boolean = false; +export class Segment extends Ion { + _disabled: boolean = false; /** * @private */ value: string; - /** @internal */ - _color: string; - /** * @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`. */ @Input() - get color(): string { - return this._color; + set color(val: string) { + this._setColor('segment', val); } - set color(value: string) { - this._updateColor(value); + /** + * @input {string} The mode to apply to this component. + */ + set mode(val: string) { + this._setMode('segment', val); } /** @@ -212,10 +213,15 @@ export class Segment { @ContentChildren(SegmentButton) _buttons: QueryList; constructor( - private _elementRef: ElementRef, - private _renderer: Renderer, + config: Config, + elementRef: ElementRef, + renderer: Renderer, @Optional() ngControl: NgControl ) { + super(config, elementRef, renderer); + + this.mode = config.get('mode'); + if (ngControl) { ngControl.valueAccessor = this; } @@ -233,28 +239,9 @@ export class Segment { this._disabled = isTrueProperty(val); if (this._buttons) { - let buttons = this._buttons.toArray(); - for (let button of buttons) { - button.setCssClass('segment-button-disabled', this._disabled); - } - } - } - - /** - * @internal - */ - _updateColor(newColor: string) { - this._setElementColor(this._color, false); - this._setElementColor(newColor, true); - this._color = newColor; - } - - /** - * @internal - */ - _setElementColor(color: string, isAdd: boolean) { - if (color !== null && color !== '') { - this._renderer.setElementClass(this._elementRef.nativeElement, `segment-${color}`, isAdd); + this._buttons.forEach(button => { + button._setCssClass('segment-button-disabled', this._disabled); + }); } } @@ -276,8 +263,7 @@ export class Segment { * @private */ ngAfterViewInit() { - let buttons = this._buttons.toArray(); - for (let button of buttons) { + this._buttons.forEach(button => { button.ionSelect.subscribe((selectedButton: any) => { this.writeValue(selectedButton.value); this.onChange(selectedButton.value); @@ -289,10 +275,9 @@ export class Segment { } if (isTrueProperty(this._disabled)) { - button.setCssClass('segment-button-disabled', this._disabled); + button._setCssClass('segment-button-disabled', this._disabled); } - - } + }); } /** diff --git a/src/components/spinner/spinner.ts b/src/components/spinner/spinner.ts index 5e55df0830..bd88965e62 100644 --- a/src/components/spinner/spinner.ts +++ b/src/components/spinner/spinner.ts @@ -1,7 +1,7 @@ import { ChangeDetectionStrategy, Component, ElementRef, Input, Renderer, ViewEncapsulation } from '@angular/core'; -import { NgFor, NgStyle } from '@angular/common'; import { Config } from '../../config/config'; +import { Ion } from '../ion'; /** * @name Spinner @@ -98,31 +98,26 @@ import { Config } from '../../config/config'; */ @Component({ selector: 'ion-spinner', - template: ` - - - - - - - `, - directives: [NgFor, NgStyle], + template: + '' + + '' + + '' + + '' + + '' + + '', host: { '[class.spinner-paused]': 'paused' }, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, }) -export class Spinner { - private _c: any[]; - private _l: any[]; - private _name: string; - private _dur: number = null; - private _init: boolean; - private _applied: string; - - /** @internal */ - _color: string; +export class Spinner extends Ion { + _c: any[]; + _l: any[]; + _name: string; + _dur: number = null; + _init: boolean; + _applied: string; /** * @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`. @@ -131,10 +126,9 @@ export class Spinner { get color(): string { return this._color; } - set color(value: string) { - this._updateColor(value); - } + this._setColor('spinner', value); + } /** * @input {string} SVG spinner name. @@ -167,11 +161,9 @@ export class Spinner { */ @Input() paused: boolean = false; - constructor( - private _config: Config, - private _elementRef: ElementRef, - private _renderer: Renderer - ) {} + constructor(config: Config, elementRef: ElementRef, renderer: Renderer) { + super(config, elementRef, renderer); + } /** * @private @@ -206,7 +198,7 @@ export class Spinner { } } - this._renderer.setElementClass(this._elementRef.nativeElement, this._applied, true); + this.setElementClass(this._applied, true); } } } @@ -218,24 +210,6 @@ export class Spinner { return data; } - /** - * @internal - */ - _updateColor(newColor: string) { - this._setElementColor(this._color, false); - this._setElementColor(newColor, true); - this._color = newColor; - } - - /** - * @internal - */ - _setElementColor(color: string, isAdd: boolean) { - if (color !== null && color !== '') { - this._renderer.setElementClass(this._elementRef.nativeElement, `spinner-${color}`, isAdd); - } - } - } const SPINNERS: any = { diff --git a/src/components/toast/toast-component.ts b/src/components/toast/toast-component.ts index 4a17f2f9ee..c765030ef5 100644 --- a/src/components/toast/toast-component.ts +++ b/src/components/toast/toast-component.ts @@ -1,33 +1,29 @@ import { AfterViewInit, Component, ElementRef, Renderer } from '@angular/core'; -import { NgIf } from '@angular/common'; import { Animation } from '../../animations/animation'; import { Config } from '../../config/config'; -import { isPresent } from '../../util/util'; -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'; /** -* @private -*/ + * @private + */ @Component({ selector: 'ion-toast', - template: ` -
-
-
{{d.message}}
- -
-
- `, - directives: [NgIf], + template: + '
' + + '
' + + '
{{d.message}}
' + + ' ' + + '
' + + '
', host: { 'role': 'dialog', '[attr.aria-labelledby]': 'hdrId', @@ -35,7 +31,7 @@ import { ViewController } from '../nav/view-controller'; }, }) export class ToastCmp implements AfterViewInit { - private d: { + d: { message?: string; cssClass?: string; duration?: number; @@ -44,20 +40,20 @@ export class ToastCmp implements AfterViewInit { dismissOnPageChange?: boolean; position?: string; }; - private descId: string; - private dismissTimeout: number = undefined; - private enabled: boolean; - private hdrId: string; - private id: number; + descId: string; + dismissTimeout: number = undefined; + enabled: boolean; + hdrId: string; + id: number; constructor( - private _viewCtrl: ViewController, - private _config: Config, - private _elementRef: ElementRef, + public _viewCtrl: ViewController, + public _config: Config, + public _elementRef: ElementRef, params: NavParams, renderer: Renderer - ) { - + ) { + renderer.setElementClass(_elementRef.nativeElement, `toast-${_config.get('mode')}`, true); this.d = params.data; if (this.d.cssClass) { @@ -76,10 +72,9 @@ export class ToastCmp implements AfterViewInit { ngAfterViewInit() { // if there's a `duration` set, automatically dismiss. if (this.d.duration) { - this.dismissTimeout = - setTimeout(() => { + this.dismissTimeout = (setTimeout(() => { this.dismiss('backdrop'); - }, this.d.duration); + }, this.d.duration)); } this.enabled = true; } @@ -113,21 +108,19 @@ export class ToastCmp implements AfterViewInit { class ToastSlideIn extends Transition { - constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) { - super(enteringView, leavingView, opts); - + init() { // DOM READS - let ele = enteringView.pageRef().nativeElement; + let ele = this.enteringView.pageRef().nativeElement; const wrapperEle = ele.querySelector('.toast-wrapper'); let wrapper = new Animation(wrapperEle); - if (enteringView.data && enteringView.data.position === TOAST_POSITION_TOP) { + if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_TOP) { // top // by default, it is -100% hidden (above the screen) // so move from that to 10px below top: 0px; wrapper.fromTo('translateY', '-100%', `${10}px`); - } else if (enteringView.data && enteringView.data.position === TOAST_POSITION_MIDDLE) { + } else if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_MIDDLE) { // Middle // just center it and fade it in let topPosition = Math.floor(ele.clientHeight / 2 - wrapperEle.clientHeight / 2); @@ -147,19 +140,17 @@ class ToastSlideIn extends Transition { } class ToastSlideOut 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; const wrapperEle = ele.querySelector('.toast-wrapper'); let wrapper = new Animation(wrapperEle); - if (leavingView.data && leavingView.data.position === TOAST_POSITION_TOP) { + if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_TOP) { // top // reverse arguments from enter transition wrapper.fromTo('translateY', `${10}px`, '-100%'); - } else if (leavingView.data && leavingView.data.position === TOAST_POSITION_MIDDLE) { + } else if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_MIDDLE) { // Middle // just fade it out wrapper.fromTo('opacity', 0.99, 0); @@ -175,21 +166,19 @@ class ToastSlideOut extends Transition { } class ToastMdSlideIn extends Transition { - constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) { - super(enteringView, leavingView, opts); - + init() { // DOM reads - let ele = enteringView.pageRef().nativeElement; + let ele = this.enteringView.pageRef().nativeElement; const wrapperEle = ele.querySelector('.toast-wrapper'); let wrapper = new Animation(wrapperEle); - if (enteringView.data && enteringView.data.position === TOAST_POSITION_TOP) { + if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_TOP) { // top // by default, it is -100% hidden (above the screen) // so move from that to top: 0px; wrapper.fromTo('translateY', '-100%', `0%`); - } else if (enteringView.data && enteringView.data.position === TOAST_POSITION_MIDDLE) { + } else if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_MIDDLE) { // Middle // just center it and fade it in let topPosition = Math.floor(ele.clientHeight / 2 - wrapperEle.clientHeight / 2); @@ -209,19 +198,17 @@ class ToastMdSlideIn extends Transition { } class ToastMdSlideOut 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; const wrapperEle = ele.querySelector('.toast-wrapper'); let wrapper = new Animation(wrapperEle); - if (leavingView.data && leavingView.data.position === TOAST_POSITION_TOP) { + if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_TOP) { // top // reverse arguments from enter transition wrapper.fromTo('translateY', `${0}%`, '-100%'); - } else if (leavingView.data && leavingView.data.position === TOAST_POSITION_MIDDLE) { + } else if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_MIDDLE) { // Middle // just fade it out wrapper.fromTo('opacity', 0.99, 0); @@ -237,19 +224,17 @@ class ToastMdSlideOut extends Transition { } class ToastWpPopIn 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; const wrapperEle = ele.querySelector('.toast-wrapper'); let wrapper = new Animation(wrapperEle); - if (enteringView.data && enteringView.data.position === TOAST_POSITION_TOP) { + if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_TOP) { // top wrapper.fromTo('opacity', 0.01, 1); wrapper.fromTo('scale', 1.3, 1); - } else if (enteringView.data && enteringView.data.position === TOAST_POSITION_MIDDLE) { + } else if (this.enteringView.data && this.enteringView.data.position === TOAST_POSITION_MIDDLE) { // Middle // just center it and fade it in let topPosition = Math.floor(ele.clientHeight / 2 - wrapperEle.clientHeight / 2); @@ -270,21 +255,19 @@ class ToastWpPopIn extends Transition { } class ToastWpPopOut extends Transition { - constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) { - super(enteringView, leavingView, opts); - + init() { // DOM reads - let ele = leavingView.pageRef().nativeElement; + let ele = this.leavingView.pageRef().nativeElement; const wrapperEle = ele.querySelector('.toast-wrapper'); let wrapper = new Animation(wrapperEle); - if (leavingView.data && leavingView.data.position === TOAST_POSITION_TOP) { + if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_TOP) { // top // reverse arguments from enter transition wrapper.fromTo('opacity', 0.99, 0); wrapper.fromTo('scale', 1, 1.3); - } else if (leavingView.data && leavingView.data.position === TOAST_POSITION_MIDDLE) { + } else if (this.leavingView.data && this.leavingView.data.position === TOAST_POSITION_MIDDLE) { // Middle // just fade it out wrapper.fromTo('opacity', 0.99, 0); @@ -315,4 +298,3 @@ Transition.register('toast-wp-slide-in', ToastWpPopIn); let toastIds = -1; const TOAST_POSITION_TOP = 'top'; const TOAST_POSITION_MIDDLE = 'middle'; -const TOAST_POSITION_BOTTOM = 'bottom'; diff --git a/src/components/toggle/toggle.ts b/src/components/toggle/toggle.ts index 2a1a85d889..7ff98bb8a6 100644 --- a/src/components/toggle/toggle.ts +++ b/src/components/toggle/toggle.ts @@ -1,16 +1,19 @@ -import { AfterContentInit, Component, ElementRef, EventEmitter, forwardRef, Input, OnDestroy, Optional, Output, Provider, Renderer, ViewEncapsulation } from '@angular/core'; +import { AfterContentInit, Component, ElementRef, EventEmitter, forwardRef, Input, OnDestroy, Optional, Output, Renderer, ViewEncapsulation } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { Config } from '../../config/config'; import { Form } from '../../util/form'; import { isTrueProperty } from '../../util/util'; +import { Ion } from '../ion'; import { Item } from '../item/item'; import { pointerCoord } from '../../util/dom'; import { UIEventManager } from '../../util/ui-event-manager'; - -export const TOGGLE_VALUE_ACCESSOR = new Provider( - NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => Toggle), multi: true}); - +export const TOGGLE_VALUE_ACCESSOR: any = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => Toggle), + multi: true +}; /** * @name Toggle @@ -51,54 +54,65 @@ export const TOGGLE_VALUE_ACCESSOR = new Provider( */ @Component({ selector: 'ion-toggle', - template: ` -
-
-
- - `, + template: + '
' + + '
' + + '
' + + '', host: { '[class.toggle-disabled]': '_disabled' }, providers: [TOGGLE_VALUE_ACCESSOR], encapsulation: ViewEncapsulation.None, }) -export class Toggle implements AfterContentInit, ControlValueAccessor, OnDestroy { - private _checked: boolean = false; - private _init: boolean; - private _disabled: boolean = false; - private _labelId: string; - private _activated: boolean = false; - private _startX: number; - private _fn: Function; - private _events: UIEventManager = new UIEventManager(); +export class Toggle extends Ion implements AfterContentInit, ControlValueAccessor, OnDestroy { + /** @private */ + _checked: boolean = false; + /** @private */ + _init: boolean; + /** @private */ + _disabled: boolean = false; + /** @private */ + _labelId: string; + /** @private */ + _activated: boolean = false; + /** @private */ + _startX: number; + /** @private */ + _msPrv: number = 0; + /** @private */ + _fn: Function; + /** @private */ + _events: UIEventManager = new UIEventManager(); /** * @private */ id: string; - /** @internal */ - _color: string; - /** * @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`. */ @Input() - get color(): string { - return this._color; + set color(val: string) { + this._setColor('toggle', val); } - set color(value: string) { - this._updateColor(value); - } + /** + * @input {string} The mode to apply to this component. + */ + @Input() + set mode(val: string) { + this._setMode('toggle', val); + } /** * @output {Toggle} expression to evaluate when the toggle value changes @@ -106,24 +120,28 @@ export class Toggle implements AfterContentInit, ControlValueAccessor, OnDestroy @Output() ionChange: EventEmitter = new EventEmitter(); constructor( - private _form: Form, - private _elementRef: ElementRef, - private _renderer: Renderer, - @Optional() private _item: Item + public _form: Form, + config: Config, + elementRef: ElementRef, + renderer: Renderer, + @Optional() public _item: Item ) { - this._form.register(this); + super(config, elementRef, renderer); + + this.mode = config.get('mode'); + _form.register(this); if (_item) { this.id = 'tgl-' + _item.registerInput('toggle'); this._labelId = 'lbl-' + _item.id; - this._item.setCssClass('item-toggle', true); + this._item.setElementClass('item-toggle', true); } } /** * @private */ - private pointerDown(ev: UIEvent): boolean { + pointerDown(ev: UIEvent): boolean { this._startX = pointerCoord(ev).x; this._activated = true; return true; @@ -132,7 +150,7 @@ export class Toggle implements AfterContentInit, ControlValueAccessor, OnDestroy /** * @private */ - private pointerMove(ev: UIEvent) { + pointerMove(ev: UIEvent) { if (this._startX) { let currentX = pointerCoord(ev).x; console.debug('toggle, pointerMove', ev.type, currentX); @@ -155,7 +173,7 @@ export class Toggle implements AfterContentInit, ControlValueAccessor, OnDestroy /** * @private */ - private pointerUp(ev: UIEvent) { + pointerUp(ev: UIEvent) { if (this._startX) { let endX = pointerCoord(ev).x; @@ -186,14 +204,16 @@ export class Toggle implements AfterContentInit, ControlValueAccessor, OnDestroy this.onChange(this._checked); } - - private _setChecked(isChecked: boolean) { + /** + * @private + */ + _setChecked(isChecked: boolean) { if (!this._disabled && isChecked !== this._checked) { this._checked = isChecked; if (this._init) { this.ionChange.emit(this); } - this._item && this._item.setCssClass('item-toggle-checked', isChecked); + this._item && this._item.setElementClass('item-toggle-checked', isChecked); } } @@ -232,26 +252,8 @@ export class Toggle implements AfterContentInit, ControlValueAccessor, OnDestroy set disabled(val: boolean) { this._disabled = isTrueProperty(val); - this._item && this._item.setCssClass('item-toggle-disabled', this._disabled); + this._item && this._item.setElementClass('item-toggle-disabled', this._disabled); } - - /** - * @internal - */ - _updateColor(newColor: string) { - this._setElementColor(this._color, false); - this._setElementColor(newColor, true); - this._color = newColor; - } - - /** - * @internal - */ - _setElementColor(color: string, isAdd: boolean) { - if (color !== null && color !== '') { - this._renderer.setElementClass(this._elementRef.nativeElement, `toggle-${color}`, isAdd); - } - } /** * @private diff --git a/src/components/toolbar/toolbar-item.ts b/src/components/toolbar/toolbar-item.ts index 04ea4d62e5..bd9d8ddea1 100644 --- a/src/components/toolbar/toolbar-item.ts +++ b/src/components/toolbar/toolbar-item.ts @@ -1,6 +1,8 @@ -import { Directive, ElementRef, Optional, forwardRef, Inject, ContentChildren } from '@angular/core'; +import { ContentChildren, Directive, ElementRef, forwardRef, Optional, Inject, Renderer } from '@angular/core'; import { Button } from '../button/button'; +import { Config } from '../../config/config'; +import { Ion } from '../ion'; import { Navbar } from '../navbar/navbar'; import { Toolbar } from './toolbar'; @@ -11,16 +13,19 @@ import { Toolbar } from './toolbar'; @Directive({ selector: 'ion-buttons,[menuToggle]' }) -export class ToolbarItem { +export class ToolbarItem extends Ion { inToolbar: boolean; constructor( + config: Config, elementRef: ElementRef, + renderer: Renderer, @Optional() toolbar: Toolbar, @Optional() @Inject(forwardRef(() => Navbar)) navbar: Navbar ) { - toolbar && toolbar.addItemRef(elementRef); - navbar && navbar.addItemRef(elementRef); + super(config, elementRef, renderer); + + this._setMode('bar-buttons', config.get('mode')); this.inToolbar = !!(toolbar || navbar); } diff --git a/src/components/toolbar/toolbar-title.ts b/src/components/toolbar/toolbar-title.ts index 707df9ddc6..bf998cd989 100644 --- a/src/components/toolbar/toolbar-title.ts +++ b/src/components/toolbar/toolbar-title.ts @@ -1,5 +1,6 @@ -import { Component, ElementRef, Optional, forwardRef, Inject, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { ChangeDetectionStrategy, Component, ElementRef, forwardRef, Optional, Inject, Renderer, ViewEncapsulation } from '@angular/core'; +import { Config } from '../../config/config'; import { Ion } from '../ion'; import { Navbar } from '../navbar/navbar'; import { Toolbar } from './toolbar'; @@ -43,7 +44,7 @@ import { Toolbar } from './toolbar'; @Component({ selector: 'ion-title', template: - '
' + + '
' + '' + '
', changeDetection: ChangeDetectionStrategy.OnPush, @@ -51,13 +52,17 @@ import { Toolbar } from './toolbar'; }) export class ToolbarTitle extends Ion { constructor( - private _elementRef: ElementRef, + config: Config, + elementRef: ElementRef, + renderer: Renderer, @Optional() toolbar: Toolbar, @Optional() @Inject(forwardRef(() => Navbar)) navbar: Navbar ) { - super(_elementRef); - toolbar && toolbar.setTitleCmp(this); - navbar && navbar.setTitleCmp(this); + super(config, elementRef, renderer); + this._setMode('title', this._mode = config.get('mode')); + + toolbar && toolbar._setTitle(this); + navbar && navbar._setTitle(this); } /** diff --git a/src/components/toolbar/toolbar.ts b/src/components/toolbar/toolbar.ts index deb63a95a3..cbd1066e8f 100644 --- a/src/components/toolbar/toolbar.ts +++ b/src/components/toolbar/toolbar.ts @@ -1,8 +1,9 @@ -import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, Directive, ElementRef, Input, Optional, QueryList, Renderer, ViewEncapsulation } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Directive, ElementRef, Input, Optional, Renderer } from '@angular/core'; import { Config } from '../../config/config'; import { Ion } from '../ion'; -import { ViewController } from '../nav/view-controller'; +import { ToolbarTitle } from './toolbar-title'; +import { ViewController } from '../../navigation/view-controller'; /** @@ -35,10 +36,12 @@ import { ViewController } from '../nav/view-controller'; @Directive({ selector: 'ion-header' }) -export class Header { +export class Header extends Ion { - constructor(@Optional() viewCtrl: ViewController) { - viewCtrl && viewCtrl.setHeader(this); + constructor(config: Config, elementRef: ElementRef, renderer: Renderer, @Optional() viewCtrl: ViewController) { + super(config, elementRef, renderer); + this._setMode('header', config.get('mode')); + viewCtrl && viewCtrl._setHeader(this); } } @@ -69,10 +72,12 @@ export class Header { @Directive({ selector: 'ion-footer' }) -export class Footer { +export class Footer extends Ion { - constructor(@Optional() viewCtrl: ViewController) { - viewCtrl && viewCtrl.setFooter(this); + constructor(config: Config, elementRef: ElementRef, renderer: Renderer, @Optional() viewCtrl: ViewController) { + super(config, elementRef, renderer); + this._setMode('footer', config.get('mode')); + viewCtrl && viewCtrl._setFooter(this); } } @@ -82,19 +87,17 @@ export class Footer { * @private */ export class ToolbarBase extends Ion { - itemRefs: ElementRef[] = []; - titleRef: any = null; - titleCmp: any; + private _title: ToolbarTitle; - constructor(elementRef: ElementRef) { - super(elementRef); + constructor(config: Config, elementRef: ElementRef, renderer: Renderer) { + super(config, elementRef, renderer); } /** * @private */ - setTitleCmp(titleCmp: any) { - this.titleCmp = titleCmp; + _setTitle(titleCmp: ToolbarTitle) { + this._title = titleCmp; } /** @@ -102,31 +105,7 @@ export class ToolbarBase extends Ion { * Returns the toolbar title text if it exists or an empty string */ getTitleText() { - return (this.titleCmp && this.titleCmp.getTitleText()) || ''; - } - - /** - * @private - */ - getTitleRef() { - return this.titleCmp && this.titleCmp.elementRef; - } - - /** - * @private - * A toolbar items include the left and right side `ion-buttons`, - * and every `menu-toggle`. It does not include the `ion-title`. - * @returns {TODO} Array of this toolbar's item ElementRefs. - */ - getItemRefs() { - return this.itemRefs; - } - - /** - * @private - */ - addItemRef(itemElementRef: ElementRef) { - this.itemRefs.push(itemElementRef); + return (this._title && this._title.getTitleText()) || ''; } } @@ -267,15 +246,14 @@ export class ToolbarBase extends Ion { */ @Component({ selector: 'ion-toolbar', - template: ` -
- - - -
- -
- `, + template: + '
' + + '' + + '' + + '' + + '
' + + '' + + '
', host: { 'class': 'toolbar', '[class.statusbar-padding]': '_sbPadding' @@ -283,59 +261,35 @@ export class ToolbarBase extends Ion { changeDetection: ChangeDetectionStrategy.OnPush, }) export class Toolbar extends ToolbarBase { - private _sbPadding: boolean; - - /** @internal */ - _color: string; + /** @private */ + _sbPadding: boolean; /** * @input {string} The predefined color to use. For example: `"primary"`, `"secondary"`, `"danger"`. */ @Input() - get color(): string { - return this._color; + set color(val: string) { + this._setColor('toolbar', val); } - set color(value: string) { - this._updateColor(value); + /** + * @input {string} The mode to apply to this component. + */ + @Input() + set mode(val: string) { + this._setMode('toolbar', val); } constructor( @Optional() viewCtrl: ViewController, - @Optional() header: Header, - @Optional() footer: Footer, config: Config, - private _elementRef: ElementRef, - private _renderer: Renderer + elementRef: ElementRef, + renderer: Renderer ) { - super(_elementRef); - - if (viewCtrl && (header || footer)) { - // only toolbars within headers and footer are view toolbars - // toolbars within the content are not view toolbars, since they - // are apart of the content, and could be anywhere within the content - viewCtrl.setToolbarRef(_elementRef); - } + super(config, elementRef, renderer); + this.mode = config.get('mode'); this._sbPadding = config.getBoolean('statusbarPadding'); } - /** - * @internal - */ - _updateColor(newColor: string) { - this._setElementColor(this._color, false); - this._setElementColor(newColor, true); - this._color = newColor; - } - - /** - * @internal - */ - _setElementColor(color: string, isAdd: boolean) { - if (color !== null && color !== '') { - this._renderer.setElementClass(this._elementRef.nativeElement, `toolbar-${color}`, isAdd); - } - } - }