From 387f883be34fbd484092c416fa66a89fd8c545db Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Thu, 7 Jan 2016 12:29:01 -0600 Subject: [PATCH] refactor(input): split TextInput and ItemInput components Make it easier to start adding other inputs, like select --- ionic/components.ios.scss | 2 +- ionic/components.md.scss | 2 +- ionic/components/app/normalize.scss | 7 + .../item-input.ios.scss} | 6 +- .../item-input.md.scss} | 4 +- .../item-input.scss} | 36 +- ionic/components/item-input/item-input.ts | 534 +++++++++++++++++ .../test/fixed-inline-labels/e2e.ts | 0 .../test/fixed-inline-labels/index.ts | 0 .../test/fixed-inline-labels/main.html | 0 .../test/floating-labels/e2e.ts | 0 .../test/floating-labels/index.ts | 0 .../test/floating-labels/main.html | 0 .../test/form-inputs/e2e.ts | 0 .../test/form-inputs/index.ts | 0 .../test/form-inputs/main.html | 0 .../test/inline-labels/e2e.ts | 0 .../test/inline-labels/index.ts | 0 .../test/inline-labels/main.html | 0 .../test/input-focus/index.ts | 0 .../test/input-focus/main.html | 0 .../test/inset-inputs/e2e.ts | 0 .../test/inset-inputs/index.ts | 0 .../test/inset-inputs/main.html | 0 .../test/placeholder-labels/e2e.ts | 0 .../test/placeholder-labels/index.ts | 0 .../test/placeholder-labels/main.html | 0 .../test/stacked-labels/e2e.ts | 0 .../test/stacked-labels/index.ts | 0 .../test/stacked-labels/main.html | 0 .../test/text-input.spec.ts | 16 +- ionic/components/text-input/text-input.ts | 539 +----------------- ionic/config/directives.ts | 7 +- 33 files changed, 573 insertions(+), 580 deletions(-) rename ionic/components/{text-input/text-input.ios.scss => item-input/item-input.ios.scss} (97%) rename ionic/components/{text-input/text-input.md.scss => item-input/item-input.md.scss} (98%) rename ionic/components/{text-input/text-input.scss => item-input/item-input.scss} (72%) create mode 100644 ionic/components/item-input/item-input.ts rename ionic/components/{text-input => item-input}/test/fixed-inline-labels/e2e.ts (100%) rename ionic/components/{text-input => item-input}/test/fixed-inline-labels/index.ts (100%) rename ionic/components/{text-input => item-input}/test/fixed-inline-labels/main.html (100%) rename ionic/components/{text-input => item-input}/test/floating-labels/e2e.ts (100%) rename ionic/components/{text-input => item-input}/test/floating-labels/index.ts (100%) rename ionic/components/{text-input => item-input}/test/floating-labels/main.html (100%) rename ionic/components/{text-input => item-input}/test/form-inputs/e2e.ts (100%) rename ionic/components/{text-input => item-input}/test/form-inputs/index.ts (100%) rename ionic/components/{text-input => item-input}/test/form-inputs/main.html (100%) rename ionic/components/{text-input => item-input}/test/inline-labels/e2e.ts (100%) rename ionic/components/{text-input => item-input}/test/inline-labels/index.ts (100%) rename ionic/components/{text-input => item-input}/test/inline-labels/main.html (100%) rename ionic/components/{text-input => item-input}/test/input-focus/index.ts (100%) rename ionic/components/{text-input => item-input}/test/input-focus/main.html (100%) rename ionic/components/{text-input => item-input}/test/inset-inputs/e2e.ts (100%) rename ionic/components/{text-input => item-input}/test/inset-inputs/index.ts (100%) rename ionic/components/{text-input => item-input}/test/inset-inputs/main.html (100%) rename ionic/components/{text-input => item-input}/test/placeholder-labels/e2e.ts (100%) rename ionic/components/{text-input => item-input}/test/placeholder-labels/index.ts (100%) rename ionic/components/{text-input => item-input}/test/placeholder-labels/main.html (100%) rename ionic/components/{text-input => item-input}/test/stacked-labels/e2e.ts (100%) rename ionic/components/{text-input => item-input}/test/stacked-labels/index.ts (100%) rename ionic/components/{text-input => item-input}/test/stacked-labels/main.html (100%) rename ionic/components/{text-input => item-input}/test/text-input.spec.ts (89%) diff --git a/ionic/components.ios.scss b/ionic/components.ios.scss index 7e9cfa23e4..e81c871ad4 100644 --- a/ionic/components.ios.scss +++ b/ionic/components.ios.scss @@ -14,6 +14,7 @@ "components/checkbox/checkbox.ios", "components/content/content.ios", "components/item/item.ios", + "components/item-input/item-input.ios", "components/label/label.ios", "components/list/list.ios", "components/menu/menu.ios", @@ -22,7 +23,6 @@ "components/searchbar/searchbar.ios", "components/segment/segment.ios", "components/tabs/tabs.ios", - "components/text-input/text-input.ios", "components/toggle/toggle.ios", "components/toolbar/toolbar.ios"; diff --git a/ionic/components.md.scss b/ionic/components.md.scss index 044c00ddaa..344d2ff803 100644 --- a/ionic/components.md.scss +++ b/ionic/components.md.scss @@ -14,6 +14,7 @@ "components/checkbox/checkbox.md", "components/content/content.md", "components/item/item.md", + "components/item-input/item-input.md", "components/label/label.md", "components/list/list.md", "components/menu/menu.md", @@ -23,6 +24,5 @@ "components/searchbar/searchbar.md", "components/segment/segment.md", "components/tabs/tabs.md", - "components/text-input/text-input.md", "components/toggle/toggle.md", "components/toolbar/toolbar.md"; diff --git a/ionic/components/app/normalize.scss b/ionic/components/app/normalize.scss index bcc2795f75..20e5657f94 100644 --- a/ionic/components/app/normalize.scss +++ b/ionic/components/app/normalize.scss @@ -94,6 +94,13 @@ textarea { font-family: inherit; } +textarea { + height: auto; + overflow: auto; + font: inherit; + color: inherit; +} + form, input, optgroup, diff --git a/ionic/components/text-input/text-input.ios.scss b/ionic/components/item-input/item-input.ios.scss similarity index 97% rename from ionic/components/text-input/text-input.ios.scss rename to ionic/components/item-input/item-input.ios.scss index f16eddfd79..a68bbaa334 100644 --- a/ionic/components/text-input/text-input.ios.scss +++ b/ionic/components/item-input/item-input.ios.scss @@ -1,7 +1,7 @@ @import "../../globals.ios"; -@import "./text-input"; +@import "./item-input"; -// iOS Text Input +// iOS Input // -------------------------------------------------- $text-input-ios-background-color: $list-ios-background-color !default; @@ -57,5 +57,5 @@ ion-input[clearInput] { @include svg-background-image($text-input-ios-input-clear-icon-svg); background-size: $text-input-ios-input-clear-icon-size; right: ($item-ios-padding-right / 2); - bottom: 0; + bottom: 0; } diff --git a/ionic/components/text-input/text-input.md.scss b/ionic/components/item-input/item-input.md.scss similarity index 98% rename from ionic/components/text-input/text-input.md.scss rename to ionic/components/item-input/item-input.md.scss index 99f96198a7..fcd9129956 100644 --- a/ionic/components/text-input/text-input.md.scss +++ b/ionic/components/item-input/item-input.md.scss @@ -1,7 +1,7 @@ @import "../../globals.md"; -@import "./text-input"; +@import "./item-input"; -// Material Design Text Input +// Material Design Input // -------------------------------------------------- $text-input-md-background-color: $list-md-background-color !default; diff --git a/ionic/components/text-input/text-input.scss b/ionic/components/item-input/item-input.scss similarity index 72% rename from ionic/components/text-input/text-input.scss rename to ionic/components/item-input/item-input.scss index 23cc93ae54..3c4cac6df0 100644 --- a/ionic/components/text-input/text-input.scss +++ b/ionic/components/item-input/item-input.scss @@ -1,12 +1,6 @@ @import "../../globals.core"; -// Text Input -// -------------------------------------------------- - -$text-input-textarea-resize: none !default; - - -// All Inputs in ion-input +// Input // -------------------------------------------------- .item-input { @@ -21,6 +15,15 @@ input.item-input:-webkit-autofill { background-color: transparent; } +input, +textarea { + @include placeholder(); +} + +.platform-mobile textarea { + resize: none; +} + // Scroll Assist // -------------------------------------------------- @@ -43,25 +46,6 @@ input.item-input:-webkit-autofill { } -// Input textarea -// -------------------------------------------------- - -textarea { - height: auto; - overflow: auto; - font: inherit; - color: inherit; -} - -.platform-mobile textarea { - resize: $text-input-textarea-resize; -} - -input, -textarea { - @include placeholder(); -} - // Clear Input Icon // -------------------------------------------------- diff --git a/ionic/components/item-input/item-input.ts b/ionic/components/item-input/item-input.ts new file mode 100644 index 0000000000..1bded24197 --- /dev/null +++ b/ionic/components/item-input/item-input.ts @@ -0,0 +1,534 @@ +import {Component, Directive, Attribute, forwardRef, Host, Optional, ElementRef, Renderer, Input, ContentChild, ContentChildren, HostListener} from 'angular2/core'; +import {NgIf} from 'angular2/common'; + +import {NavController} from '../nav/nav-controller'; +import {Config} from '../../config/config'; +import {Form} from '../../util/form'; +import {Label} from '../label/label'; +import {TextInput} from '../text-input/text-input'; +import {IonicApp} from '../app/app'; +import {Content} from '../content/content'; +import {pointerCoord, hasPointerMoved} from '../../util/dom'; +import {Platform} from '../../platform/platform'; +import {Button} from '../button/button'; +import {Icon} from '../icon/icon'; + + +/** + * @name Input + * @module ionic + * @description + * + * `ion-input` is a generic wrapper for both inputs and textareas. You can give `ion-input` attributes to tell it how to handle a child `ion-label` component. + * + * @property [fixed-label] - a persistant label that sits next the the input + * @property [floating-label] - a label that will float about the input if the input is empty of looses focus + * @property [stacked-label] - A stacked label will always appear on top of the input + * @property [inset] - The input will be inset + * @property [clearInput] - A clear icon will appear in the input which clears it + * + * @usage + * ```html + * + * Username + * + * + * + * + * + * + * + * + * Username + * + * + * + * + * Username + * + * + * ``` + * + */ + +@Component({ + selector: 'ion-input', + host: { + '(touchstart)': 'pointerStart($event)', + '(touchend)': 'pointerEnd($event)', + '(mouseup)': 'pointerEnd($event)', + 'class': 'item', + '[class.ng-untouched]': 'hasClass("ng-untouched")', + '[class.ng-touched]': 'hasClass("ng-touched")', + '[class.ng-pristine]': 'hasClass("ng-pristine")', + '[class.ng-dirty]': 'hasClass("ng-dirty")', + '[class.ng-valid]': 'hasClass("ng-valid")', + '[class.ng-invalid]': 'hasClass("ng-invalid")' + }, + template: + '
' + + '' + + '' + + '' + + '
', + directives: [NgIf, forwardRef(() => InputScrollAssist), TextInput, Button] +}) +export class ItemInput { + /** + * @private + */ + @Input() clearInput: any; + value: string = ''; + + constructor( + config: Config, + private _form: Form, + private _renderer: Renderer, + private _elementRef: ElementRef, + private _app: IonicApp, + private _platform: Platform, + @Optional() @Host() private _scrollView: Content, + @Optional() private _nav: NavController, + @Attribute('floating-label') isFloating: string, + @Attribute('stacked-label') isStacked: string, + @Attribute('fixed-label') isFixed: string, + @Attribute('inset') isInset: string + ) { + _form.register(this); + + this.type = null; + this.lastTouch = 0; + + // make more gud with pending @Attributes API + this.displayType = (isFloating === '' ? 'floating' : (isStacked === '' ? 'stacked' : (isFixed === '' ? 'fixed' : (isInset === '' ? 'inset' : null)))); + + this._assist = config.get('scrollAssist'); + this.keyboardHeight = config.get('keyboardHeight'); + } + + /** + * @private + */ + @ContentChild(TextInput) + set _setInput(textInput) { + if (textInput) { + textInput.addClass('item-input'); + if (this.displayType) { + textInput.addClass(this.displayType + '-input'); + } + this.input = textInput; + this.type = textInput.type; + + this.hasValue(this.input.value); + textInput.valueChange.subscribe(inputValue => { + this.hasValue(inputValue); + }); + + this.focusChange(this.hasFocus()); + textInput.focusChange.subscribe(textInputHasFocus => { + this.focusChange(textInputHasFocus); + }); + } + } + + /** + * @private + */ + @ContentChild(Label) + set _setLabel(label) { + if (label && this.displayType) { + label.addClass(this.displayType + '-label'); + } + this.label = label; + } + + /** + * @private + */ + @ContentChildren(Button) + set _buttons(buttons) { + buttons.toArray().forEach(button => { + if (!button.isItem) { + button.addClass('item-button'); + } + }); + } + + /** + * @private + */ + @ContentChildren(Icon) + set _icons(icons) { + icons.toArray().forEach(icon => { + icon.addClass('item-icon'); + }); + } + + /** + * @private + * On Initialization check for attributes + */ + ngOnInit() { + let clearInput = this.clearInput; + if (typeof clearInput === 'string') { + this.clearInput = (clearInput === '' || clearInput === 'true'); + } + } + + /** + * @private + */ + ngAfterViewInit() { + let self = this; + if (self.input && self.label) { + // if there is an input and a label + // then give the label an ID + // and tell the input the ID of who it's labelled by + self.input.labelledBy(self.label.id); + } + + self.scrollMove = function(ev) { + if (!(self._nav && self._nav.isTransitioning())) { + self.deregMove(); + + if (self.hasFocus()) { + self.input.hideFocus(true); + self._scrollView.onScrollEnd(function() { + self.input.hideFocus(false); + + if (self.hasFocus()) { + self.regMove(); + } + }); + } + } + }; + } + + /** + * @private + */ + clearTextInput() { + console.log("Should clear input"); + //console.log(this.textInput.value); + } + + /** + * @private + */ + pointerStart(ev) { + if (this._assist && this._app.isEnabled()) { + // remember where the touchstart/mousedown started + this.startCoord = pointerCoord(ev); + } + } + + /** + * @private + */ + pointerEnd(ev) { + if (!this._app.isEnabled()) { + ev.preventDefault(); + ev.stopPropagation(); + + } else if (this._assist && ev.type === 'touchend') { + // get where the touchend/mouseup ended + let endCoord = pointerCoord(ev); + + // focus this input if the pointer hasn't moved XX pixels + // and the input doesn't already have focus + if (!hasPointerMoved(8, this.startCoord, endCoord) && !this.hasFocus()) { + ev.preventDefault(); + ev.stopPropagation(); + + this.initFocus(); + + // temporarily prevent mouseup's from focusing + this.lastTouch = Date.now(); + } + + } else if (this.lastTouch + 999 < Date.now()) { + ev.preventDefault(); + ev.stopPropagation(); + + this.setFocus(); + this.regMove(); + } + } + + /** + * @private + */ + initFocus() { + // begin the process of setting focus to the inner input element + + let scrollView = this._scrollView; + + if (scrollView && this._assist) { + // this input is inside of a scroll view + + // find out if text input should be manually scrolled into view + let ele = this._elementRef.nativeElement; + + let scrollData = ItemInput.getScrollData(ele.offsetTop, ele.offsetHeight, scrollView.getDimensions(), this.keyboardHeight, this._platform.height()); + if (scrollData.scrollAmount > -3 && scrollData.scrollAmount < 3) { + // the text input is in a safe position that doesn't require + // it to be scrolled into view, just set focus now + this.setFocus(); + this.regMove(); + return; + } + + // add padding to the bottom of the scroll view (if needed) + scrollView.addScrollPadding(scrollData.scrollPadding); + + // manually scroll the text input to the top + // do not allow any clicks while it's scrolling + let scrollDuration = getScrollAssistDuration(scrollData.scrollAmount); + this._app.setEnabled(false, scrollDuration); + this._nav && this._nav.setTransitioning(true, scrollDuration); + + // temporarily move the focus to the focus holder so the browser + // doesn't freak out while it's trying to get the input in place + // at this point the native text input still does not have focus + this.input.relocate(true, scrollData.inputSafeY); + + // scroll the input into place + scrollView.scrollTo(0, scrollData.scrollTo, scrollDuration).then(() => { + // the scroll view is in the correct position now + // give the native text input focus + this.input.relocate(false); + + // all good, allow clicks again + this._app.setEnabled(true); + this._nav && this._nav.setTransitioning(false); + this.regMove(); + }); + + } else { + // not inside of a scroll view, just focus it + this.setFocus(); + this.regMove(); + } + + } + + /** + * @private + */ + setFocus() { + if (this.input) { + this._form.setAsFocused(this); + + // set focus on the actual input element + this.input.setFocus(); + + // ensure the body hasn't scrolled down + document.body.scrollTop = 0; + } + } + + /** + * @private + */ + regMove() { + if (this._assist && this._scrollView) { + setTimeout(() => { + this.deregMove(); + this.deregScroll = this._scrollView.addScrollEventListener(this.scrollMove); + }, 80); + } + } + + /** + * @private + */ + deregMove() { + this.deregScroll && this.deregScroll(); + } + + /** + * @private + */ + focusChange(inputHasFocus) { + this._renderer.setElementClass(this._elementRef, 'input-focused', inputHasFocus); + if (!inputHasFocus) { + this.deregMove(); + } + } + + /** + * @private + */ + hasFocus() { + return !!this.input && this.input.hasFocus(); + } + + /** + * @private + */ + hasValue(inputValue) { + let inputHasValue = !!(inputValue && inputValue !== ''); + this._renderer.setElementClass(this._elementRef, 'input-has-value', inputHasValue); + } + + /** + * @private + * This function is used to add the Angular css classes associated with inputs in forms + */ + hasClass(className) { + this.input && this.input.hasClass(className); + } + + /** + * @private + */ + ngOnDestroy() { + this.deregMove(); + this._form.deregister(this); + } + + /** + * @private + */ + static getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, plaformHeight) { + // compute input's Y values relative to the body + let inputTop = (inputOffsetTop + scrollViewDimensions.contentTop - scrollViewDimensions.scrollTop); + let inputBottom = (inputTop + inputOffsetHeight); + + // compute the safe area which is the viewable content area when the soft keyboard is up + let safeAreaTop = scrollViewDimensions.contentTop; + let safeAreaHeight = plaformHeight - keyboardHeight - safeAreaTop; + safeAreaHeight /= 2; + let safeAreaBottom = safeAreaTop + safeAreaHeight; + + let inputTopWithinSafeArea = (inputTop >= safeAreaTop && inputTop <= safeAreaBottom); + let inputTopAboveSafeArea = (inputTop < safeAreaTop); + let inputTopBelowSafeArea = (inputTop > safeAreaBottom); + let inputBottomWithinSafeArea = (inputBottom >= safeAreaTop && inputBottom <= safeAreaBottom); + let inputBottomBelowSafeArea = (inputBottom > safeAreaBottom); + + /* + Text Input Scroll To Scenarios + --------------------------------------- + 1) Input top within safe area, bottom within safe area + 2) Input top within safe area, bottom below safe area, room to scroll + 3) Input top above safe area, bottom within safe area, room to scroll + 4) Input top below safe area, no room to scroll, input smaller than safe area + 5) Input top within safe area, bottom below safe area, no room to scroll, input smaller than safe area + 6) Input top within safe area, bottom below safe area, no room to scroll, input larger than safe area + 7) Input top below safe area, no room to scroll, input larger than safe area + */ + + let scrollData = { + scrollAmount: 0, + scrollTo: 0, + scrollPadding: 0, + inputSafeY: 0 + }; + + if (inputTopWithinSafeArea && inputBottomWithinSafeArea) { + // Input top within safe area, bottom within safe area + // no need to scroll to a position, it's good as-is + return scrollData; + } + + // looks like we'll have to do some auto-scrolling + if (inputTopBelowSafeArea || inputBottomBelowSafeArea) { + // Input top and bottom below safe area + // auto scroll the input up so at least the top of it shows + + if (safeAreaHeight > inputOffsetHeight) { + // safe area height is taller than the input height, so we + // can bring it up the input just enough to show the input bottom + scrollData.scrollAmount = Math.round(safeAreaBottom - inputBottom); + + } else { + // safe area height is smaller than the input height, so we can + // only scroll it up so the input top is at the top of the safe area + // however the input bottom will be below the safe area + scrollData.scrollAmount = Math.round(safeAreaTop - inputTop); + } + + scrollData.inputSafeY = -(inputTop - safeAreaTop) + 4; + + } else if (inputTopAboveSafeArea) { + // Input top above safe area + // auto scroll the input down so at least the top of it shows + scrollData.scrollAmount = Math.round(safeAreaTop - inputTop); + + scrollData.inputSafeY = (safeAreaTop - inputTop) + 4; + } + + // figure out where it should scroll to for the best position to the input + scrollData.scrollTo = (scrollViewDimensions.scrollTop - scrollData.scrollAmount); + + if (scrollData.scrollAmount < 0) { + // when auto-scrolling up, there also needs to be enough + // content padding at the bottom of the scroll view + // manually add it if there isn't enough scrollable area + + // figure out how many scrollable area is left to scroll up + let availablePadding = (scrollViewDimensions.scrollHeight - scrollViewDimensions.scrollTop) - scrollViewDimensions.contentHeight; + + let paddingSpace = availablePadding + scrollData.scrollAmount; + if (paddingSpace < 0) { + // there's not enough scrollable area at the bottom, so manually add more + scrollData.scrollPadding = (scrollViewDimensions.contentHeight - safeAreaHeight); + } + } + + // if (!window.safeAreaEle) { + // window.safeAreaEle = document.createElement('div'); + // window.safeAreaEle.style.position = 'absolute'; + // window.safeAreaEle.style.background = 'rgba(0, 128, 0, 0.7)'; + // window.safeAreaEle.style.padding = '2px 5px'; + // window.safeAreaEle.style.textShadow = '1px 1px white'; + // window.safeAreaEle.style.left = '0px'; + // window.safeAreaEle.style.right = '0px'; + // window.safeAreaEle.style.fontWeight = 'bold'; + // window.safeAreaEle.style.pointerEvents = 'none'; + // document.body.appendChild(window.safeAreaEle); + // } + // window.safeAreaEle.style.top = safeAreaTop + 'px'; + // window.safeAreaEle.style.height = safeAreaHeight + 'px'; + // window.safeAreaEle.innerHTML = ` + //
scrollTo: ${scrollData.scrollTo}
+ //
scrollAmount: ${scrollData.scrollAmount}
+ //
scrollPadding: ${scrollData.scrollPadding}
+ //
inputSafeY: ${scrollData.inputSafeY}
+ //
scrollHeight: ${scrollViewDimensions.scrollHeight}
+ //
scrollTop: ${scrollViewDimensions.scrollTop}
+ //
contentHeight: ${scrollViewDimensions.contentHeight}
+ // `; + + return scrollData; + } + +} + +/** + * @private + */ +@Directive({ + selector: '[scroll-assist]' +}) +class InputScrollAssist { + + constructor(private _form: Form, private _input: ItemInput) {} + + @HostListener('focus') + receivedFocus() { + this._form.focusNext(this._input); + } + +} + +const SCROLL_ASSIST_SPEED = 0.4; + +function getScrollAssistDuration(distanceToScroll) { + //return 3000; + distanceToScroll = Math.abs(distanceToScroll); + let duration = distanceToScroll / SCROLL_ASSIST_SPEED; + return Math.min(400, Math.max(100, duration)); +} diff --git a/ionic/components/text-input/test/fixed-inline-labels/e2e.ts b/ionic/components/item-input/test/fixed-inline-labels/e2e.ts similarity index 100% rename from ionic/components/text-input/test/fixed-inline-labels/e2e.ts rename to ionic/components/item-input/test/fixed-inline-labels/e2e.ts diff --git a/ionic/components/text-input/test/fixed-inline-labels/index.ts b/ionic/components/item-input/test/fixed-inline-labels/index.ts similarity index 100% rename from ionic/components/text-input/test/fixed-inline-labels/index.ts rename to ionic/components/item-input/test/fixed-inline-labels/index.ts diff --git a/ionic/components/text-input/test/fixed-inline-labels/main.html b/ionic/components/item-input/test/fixed-inline-labels/main.html similarity index 100% rename from ionic/components/text-input/test/fixed-inline-labels/main.html rename to ionic/components/item-input/test/fixed-inline-labels/main.html diff --git a/ionic/components/text-input/test/floating-labels/e2e.ts b/ionic/components/item-input/test/floating-labels/e2e.ts similarity index 100% rename from ionic/components/text-input/test/floating-labels/e2e.ts rename to ionic/components/item-input/test/floating-labels/e2e.ts diff --git a/ionic/components/text-input/test/floating-labels/index.ts b/ionic/components/item-input/test/floating-labels/index.ts similarity index 100% rename from ionic/components/text-input/test/floating-labels/index.ts rename to ionic/components/item-input/test/floating-labels/index.ts diff --git a/ionic/components/text-input/test/floating-labels/main.html b/ionic/components/item-input/test/floating-labels/main.html similarity index 100% rename from ionic/components/text-input/test/floating-labels/main.html rename to ionic/components/item-input/test/floating-labels/main.html diff --git a/ionic/components/text-input/test/form-inputs/e2e.ts b/ionic/components/item-input/test/form-inputs/e2e.ts similarity index 100% rename from ionic/components/text-input/test/form-inputs/e2e.ts rename to ionic/components/item-input/test/form-inputs/e2e.ts diff --git a/ionic/components/text-input/test/form-inputs/index.ts b/ionic/components/item-input/test/form-inputs/index.ts similarity index 100% rename from ionic/components/text-input/test/form-inputs/index.ts rename to ionic/components/item-input/test/form-inputs/index.ts diff --git a/ionic/components/text-input/test/form-inputs/main.html b/ionic/components/item-input/test/form-inputs/main.html similarity index 100% rename from ionic/components/text-input/test/form-inputs/main.html rename to ionic/components/item-input/test/form-inputs/main.html diff --git a/ionic/components/text-input/test/inline-labels/e2e.ts b/ionic/components/item-input/test/inline-labels/e2e.ts similarity index 100% rename from ionic/components/text-input/test/inline-labels/e2e.ts rename to ionic/components/item-input/test/inline-labels/e2e.ts diff --git a/ionic/components/text-input/test/inline-labels/index.ts b/ionic/components/item-input/test/inline-labels/index.ts similarity index 100% rename from ionic/components/text-input/test/inline-labels/index.ts rename to ionic/components/item-input/test/inline-labels/index.ts diff --git a/ionic/components/text-input/test/inline-labels/main.html b/ionic/components/item-input/test/inline-labels/main.html similarity index 100% rename from ionic/components/text-input/test/inline-labels/main.html rename to ionic/components/item-input/test/inline-labels/main.html diff --git a/ionic/components/text-input/test/input-focus/index.ts b/ionic/components/item-input/test/input-focus/index.ts similarity index 100% rename from ionic/components/text-input/test/input-focus/index.ts rename to ionic/components/item-input/test/input-focus/index.ts diff --git a/ionic/components/text-input/test/input-focus/main.html b/ionic/components/item-input/test/input-focus/main.html similarity index 100% rename from ionic/components/text-input/test/input-focus/main.html rename to ionic/components/item-input/test/input-focus/main.html diff --git a/ionic/components/text-input/test/inset-inputs/e2e.ts b/ionic/components/item-input/test/inset-inputs/e2e.ts similarity index 100% rename from ionic/components/text-input/test/inset-inputs/e2e.ts rename to ionic/components/item-input/test/inset-inputs/e2e.ts diff --git a/ionic/components/text-input/test/inset-inputs/index.ts b/ionic/components/item-input/test/inset-inputs/index.ts similarity index 100% rename from ionic/components/text-input/test/inset-inputs/index.ts rename to ionic/components/item-input/test/inset-inputs/index.ts diff --git a/ionic/components/text-input/test/inset-inputs/main.html b/ionic/components/item-input/test/inset-inputs/main.html similarity index 100% rename from ionic/components/text-input/test/inset-inputs/main.html rename to ionic/components/item-input/test/inset-inputs/main.html diff --git a/ionic/components/text-input/test/placeholder-labels/e2e.ts b/ionic/components/item-input/test/placeholder-labels/e2e.ts similarity index 100% rename from ionic/components/text-input/test/placeholder-labels/e2e.ts rename to ionic/components/item-input/test/placeholder-labels/e2e.ts diff --git a/ionic/components/text-input/test/placeholder-labels/index.ts b/ionic/components/item-input/test/placeholder-labels/index.ts similarity index 100% rename from ionic/components/text-input/test/placeholder-labels/index.ts rename to ionic/components/item-input/test/placeholder-labels/index.ts diff --git a/ionic/components/text-input/test/placeholder-labels/main.html b/ionic/components/item-input/test/placeholder-labels/main.html similarity index 100% rename from ionic/components/text-input/test/placeholder-labels/main.html rename to ionic/components/item-input/test/placeholder-labels/main.html diff --git a/ionic/components/text-input/test/stacked-labels/e2e.ts b/ionic/components/item-input/test/stacked-labels/e2e.ts similarity index 100% rename from ionic/components/text-input/test/stacked-labels/e2e.ts rename to ionic/components/item-input/test/stacked-labels/e2e.ts diff --git a/ionic/components/text-input/test/stacked-labels/index.ts b/ionic/components/item-input/test/stacked-labels/index.ts similarity index 100% rename from ionic/components/text-input/test/stacked-labels/index.ts rename to ionic/components/item-input/test/stacked-labels/index.ts diff --git a/ionic/components/text-input/test/stacked-labels/main.html b/ionic/components/item-input/test/stacked-labels/main.html similarity index 100% rename from ionic/components/text-input/test/stacked-labels/main.html rename to ionic/components/item-input/test/stacked-labels/main.html diff --git a/ionic/components/text-input/test/text-input.spec.ts b/ionic/components/item-input/test/text-input.spec.ts similarity index 89% rename from ionic/components/text-input/test/text-input.spec.ts rename to ionic/components/item-input/test/text-input.spec.ts index 5f27d54ac2..8abc8fc69d 100644 --- a/ionic/components/text-input/test/text-input.spec.ts +++ b/ionic/components/item-input/test/text-input.spec.ts @@ -1,4 +1,4 @@ -import {TextInput} from 'ionic/ionic'; +import {ItemInput} from 'ionic/ionic'; export function run() { @@ -14,7 +14,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(-205); expect(scrollData.scrollTo).toBe(235); @@ -33,7 +33,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(-205); expect(scrollData.scrollTo).toBe(235); @@ -53,7 +53,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(150); expect(scrollData.scrollTo).toBe(100); @@ -73,7 +73,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(-80); expect(scrollData.scrollTo).toBe(100); @@ -91,7 +91,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(-20); expect(scrollData.scrollTo).toBe(20); @@ -109,7 +109,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(-180); expect(scrollData.scrollTo).toBe(180); @@ -128,7 +128,7 @@ export function run() { let keyboardHeight = 400; let platformHeight = 800; - let scrollData = TextInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); + let scrollData = ItemInput.getScrollData(inputOffsetTop, inputOffsetHeight, scrollViewDimensions, keyboardHeight, platformHeight); expect(scrollData.scrollAmount).toBe(0); }); diff --git a/ionic/components/text-input/text-input.ts b/ionic/components/text-input/text-input.ts index 440dad39ee..34034bf125 100644 --- a/ionic/components/text-input/text-input.ts +++ b/ionic/components/text-input/text-input.ts @@ -1,16 +1,6 @@ -import {Component, Directive, Attribute, forwardRef, Host, Optional, ElementRef, Renderer, Input, Output, EventEmitter, ContentChild, ContentChildren, HostListener} from 'angular2/core'; -import {NgIf} from 'angular2/common'; +import {Directive, Attribute, ElementRef, Renderer, Input, Output, EventEmitter, HostListener} from 'angular2/core'; -import {NavController} from '../nav/nav-controller'; -import {Config} from '../../config/config'; -import {Form} from '../../util/form'; -import {Label} from '../label/label'; -import {IonicApp} from '../app/app'; -import {Content} from '../content/content'; -import {CSS, hasFocus, pointerCoord, hasPointerMoved} from '../../util/dom'; -import {Platform} from '../../platform/platform'; -import {Button} from '../button/button'; -import {Icon} from '../icon/icon'; +import {CSS, hasFocus} from '../../util/dom'; /** @@ -22,7 +12,7 @@ import {Icon} from '../icon/icon'; 'class': 'text-input' } }) -export class TextInputElement { +export class TextInput { @Input() value: string; @Input() ngModel: any; @Output() valueChange: EventEmitter = new EventEmitter(); @@ -132,520 +122,6 @@ export class TextInputElement { } - -/** - * @name Input - * @module ionic - * @description - * - * `ion-input` is a generic wrapper for both inputs and textareas. You can give `ion-input` attributes to tell it how to handle a child `ion-label` component. - * - * @property [fixed-label] - a persistant label that sits next the the input - * @property [floating-label] - a label that will float about the input if the input is empty of looses focus - * @property [stacked-label] - A stacked label will always appear on top of the input - * @property [inset] - The input will be inset - * @property [clearInput] - A clear icon will appear in the input which clears it - * - * @usage - * ```html - * - * Username - * - * - * - * - * - * - * - * - * Username - * - * - * - * - * Username - * - * - * ``` - * - */ - -@Component({ - selector: 'ion-input', - host: { - '(touchstart)': 'pointerStart($event)', - '(touchend)': 'pointerEnd($event)', - '(mouseup)': 'pointerEnd($event)', - 'class': 'item', - '[class.ng-untouched]': 'hasClass("ng-untouched")', - '[class.ng-touched]': 'hasClass("ng-touched")', - '[class.ng-pristine]': 'hasClass("ng-pristine")', - '[class.ng-dirty]': 'hasClass("ng-dirty")', - '[class.ng-valid]': 'hasClass("ng-valid")', - '[class.ng-invalid]': 'hasClass("ng-invalid")' - }, - template: - '
' + - '' + - '' + - '' + - '
', - directives: [NgIf, forwardRef(() => InputScrollAssist), forwardRef(() => TextInputElement), Button] -}) -export class TextInput { - /** - * @private - */ - @Input() clearInput: any; - value: string = ''; - - constructor( - config: Config, - private _form: Form, - private _renderer: Renderer, - private _elementRef: ElementRef, - private _app: IonicApp, - private _platform: Platform, - @Optional() @Host() private _scrollView: Content, - @Optional() private _nav: NavController, - @Attribute('floating-label') isFloating: string, - @Attribute('stacked-label') isStacked: string, - @Attribute('fixed-label') isFixed: string, - @Attribute('inset') isInset: string - ) { - _form.register(this); - - this.type = 'text'; - this.lastTouch = 0; - - // make more gud with pending @Attributes API - this.displayType = (isFloating === '' ? 'floating' : (isStacked === '' ? 'stacked' : (isFixed === '' ? 'fixed' : (isInset === '' ? 'inset' : null)))); - - this._assist = config.get('scrollAssist'); - this.keyboardHeight = config.get('keyboardHeight'); - } - - /** - * @private - */ - @ContentChild(TextInputElement) - set _setInput(textInputElement) { - if (textInputElement) { - textInputElement.addClass('item-input'); - if (this.displayType) { - textInputElement.addClass(this.displayType + '-input'); - } - this.input = textInputElement; - this.type = textInputElement.type; - - this.hasValue(this.input.value); - textInputElement.valueChange.subscribe(inputValue => { - this.hasValue(inputValue); - }); - - this.focusChange(this.hasFocus()); - textInputElement.focusChange.subscribe(hasFocus => { - this.focusChange(hasFocus); - }); - - } else { - console.error(' or