refactor(components): add color/mode properties

This commit is contained in:
Brandy Carney
2016-09-13 17:11:33 -05:00
committed by Adam Bradley
parent 52ada1ca6d
commit bc7d328bc0
25 changed files with 1174 additions and 1350 deletions

View File

@@ -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<Event> = new EventEmitter<Event>();
@Output() focus: EventEmitter<Event> = new EventEmitter<Event>();
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 = <NavControllerBase>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 = <HTMLElement>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();
}

View File

@@ -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: `
<input [type]="type" [(ngModel)]="_value" (blur)="inputBlurred($event)" (focus)="inputFocused($event)" [placeholder]="placeholder" class="text-input">
<input [type]="type" aria-hidden="true" next-input *ngIf="_useAssist">
<button ion-button clear [hidden]="!clearInput" type="button" class="text-input-clear-icon" (click)="clearTextInput()" (mousedown)="clearTextInput()"></button>
<div (touchstart)="pointerStart($event)" (touchend)="pointerEnd($event)" (mousedown)="pointerStart($event)" (mouseup)="pointerEnd($event)" class="input-cover" tappable *ngIf="_useAssist"></div>
`,
directives: [NativeInput, NextInput, NgIf, NgModel],
template:
'<input [type]="type" [(ngModel)]="_value" (blur)="inputBlurred($event)" (focus)="inputFocused($event)" [placeholder]="placeholder" class="text-input" [ngClass]="\'text-input-\' + _mode">' +
'<input [type]="type" aria-hidden="true" next-input *ngIf="_useAssist">' +
'<button ion-button clear [hidden]="!clearInput" type="button" class="text-input-clear-icon" (click)="clearTextInput()" (mousedown)="clearTextInput()"></button>' +
'<div (touchstart)="pointerStart($event)" (touchend)="pointerEnd($event)" (mousedown)="pointerStart($event)" (mouseup)="pointerEnd($event)" class="input-cover" tappable *ngIf="_useAssist"></div>',
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<Event> = new EventEmitter<Event>();
/**
* @private
*/
@Output() focus: EventEmitter<Event> = new EventEmitter<Event>();
/**
* @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:
'<textarea [(ngModel)]="_value" (blur)="inputBlurred($event)" (focus)="inputFocused($event)" [placeholder]="placeholder" class="text-input"></textarea>' +
'<textarea [(ngModel)]="_value" (blur)="inputBlurred($event)" (focus)="inputFocused($event)" [placeholder]="placeholder" class="text-input" [ngClass]="\'text-input-\' + _mode"></textarea>' +
'<input type="text" aria-hidden="true" next-input *ngIf="_useAssist">' +
'<div (touchstart)="pointerStart($event)" (touchend)="pointerEnd($event)" (mousedown)="pointerStart($event)" (mouseup)="pointerEnd($event)" class="input-cover" tappable *ngIf="_useAssist"></div>',
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<Event> = new EventEmitter<Event>();
/**
* @private
*/
@Output() focus: EventEmitter<Event> = new EventEmitter<Event>();
/**
* @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
*/

View File

@@ -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<boolean> = new EventEmitter<boolean>();
@Output() valueChange: EventEmitter<string> = new EventEmitter<string>();
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)`;
(<any>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] = '';
(<any>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);
}