diff --git a/ionic/components/text-input/label.scss b/ionic/components/text-input/label.scss index 039f1b2cef..be73c35416 100644 --- a/ionic/components/text-input/label.scss +++ b/ionic/components/text-input/label.scss @@ -8,6 +8,7 @@ ion-label { max-width: 200px; font-size: inherit; white-space: nowrap; + pointer-events: none; } [fixed-label] ion-label { @@ -16,9 +17,14 @@ ion-label { max-width: 200px; } -ion-input[stacked-label] { +ion-input[stacked-label], +ion-input[floating-label] { flex-direction: column; align-items: flex-start; +} + +[stacked-label], +[floating-label] { ion-label { align-self: stretch; @@ -30,4 +36,5 @@ ion-input[stacked-label] { align-self: stretch; width: auto; } + } diff --git a/ionic/components/text-input/modes/ios.scss b/ionic/components/text-input/modes/ios.scss index 55edab4c09..aa2eea8477 100644 --- a/ionic/components/text-input/modes/ios.scss +++ b/ionic/components/text-input/modes/ios.scss @@ -28,9 +28,22 @@ ion-card[mode=ios] { margin-bottom: 4px; } - [stacked-label] .text-input { + [stacked-label] .text-input, + [floating-label] .text-input { margin-top: 8px; margin-bottom: 8px; } + [floating-label] ion-label { + margin-bottom: 0; + transform-origin: left top; + transform: translate3d(0, 27px, 0); + transition: transform 150ms ease-in-out; + } + + [floating-label].has-focus ion-label, + [floating-label].has-value ion-label { + transform: translate3d(0, 0, 0) scale(0.8); + } + } diff --git a/ionic/components/text-input/modes/material.scss b/ionic/components/text-input/modes/material.scss index a123520602..53f3ce9e46 100644 --- a/ionic/components/text-input/modes/material.scss +++ b/ionic/components/text-input/modes/material.scss @@ -43,14 +43,28 @@ ion-card[mode=md] { margin-bottom: 0; } - [stacked-label].has-focus ion-label { + [stacked-label].has-focus ion-label, + [floating-label].has-focus ion-label { color: $text-input-highlight-color; } - [stacked-label] .text-input { + [stacked-label] .text-input, + [floating-label] .text-input { margin-bottom: 8px; margin-top: 8px; } + + [floating-label] ion-label { + margin-bottom: 0; + transform-origin: left top; + transform: translate3d(0, 27px, 0); + transition: transform 150ms ease-in-out; + } + + [floating-label].has-focus ion-label, + [floating-label].has-value ion-label { + transform: translate3d(0, 0, 0) scale(0.8); + } } .list[mode=md][inset] ion-input.item { diff --git a/ionic/components/text-input/test/floating-labels/e2e.ts b/ionic/components/text-input/test/floating-labels/e2e.ts new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/ionic/components/text-input/test/floating-labels/e2e.ts @@ -0,0 +1 @@ + diff --git a/ionic/components/text-input/test/floating-labels/index.ts b/ionic/components/text-input/test/floating-labels/index.ts new file mode 100644 index 0000000000..43aed36502 --- /dev/null +++ b/ionic/components/text-input/test/floating-labels/index.ts @@ -0,0 +1,7 @@ +import {App} from 'ionic/ionic'; + + +@App({ + templateUrl: 'main.html' +}) +class E2EApp {} diff --git a/ionic/components/text-input/test/floating-labels/main.html b/ionic/components/text-input/test/floating-labels/main.html new file mode 100644 index 0000000000..774029f7ca --- /dev/null +++ b/ionic/components/text-input/test/floating-labels/main.html @@ -0,0 +1,61 @@ + +Floating Label Text Input + + + + + + + + Floating Label 1 + + + + + Floating Label 2 + + + + + Floating Label 3 + + + + + Floating Label 4 + + + + + Floating Label 5 + + + + + Floating Label 6 + + + + + Floating Label 7 + + + + + Floating Label 8 + + + + + Floating Label 9 + + + + + Floating Label 10 + + + + + + diff --git a/ionic/components/text-input/text-input.ts b/ionic/components/text-input/text-input.ts index ce236fe5bc..fa011eb993 100644 --- a/ionic/components/text-input/text-input.ts +++ b/ionic/components/text-input/text-input.ts @@ -57,6 +57,14 @@ export class TextInputElement { get hasFocus() { return dom.hasFocus(this.elementRef); } + + /** + * Whether the input has a value. + * @returns {boolean} true if the input has a value, otherwise false. + */ + get hasValue() { + return (this.elementRef.nativeElement.value !== ''); + } } /** @@ -75,6 +83,7 @@ export class TextInputElement { '(^touchend)': 'pointerEnd($event)', '(^mouseup)': 'pointerEnd($event)', '[class.has-focus]': 'inputHasFocus', + '[class.has-value]': 'inputHasValue', '[tabIndex]': 'activeTabIndex', 'class': 'item' } @@ -404,6 +413,10 @@ export class TextInput extends Ion { return !!this.input && this.input.hasFocus; } + get inputHasValue() { + return !!this.input && this.input.hasValue; + } + get activeTabIndex() { this.input.tabIndex = (this.inputHasFocus ? 1000 : -1); return -1;