From 10306871597b95f8d611de3f119dcb04b31dfad7 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Wed, 16 Aug 2017 14:41:41 -0700 Subject: [PATCH] separate the "floating" logic from the "empty" logic --- src/lib/form-field/_form-field-theme.scss | 28 +++++--------- src/lib/form-field/form-field-control.ts | 3 ++ src/lib/form-field/form-field.html | 2 - src/lib/form-field/form-field.scss | 45 +++++++++++------------ src/lib/form-field/form-field.ts | 2 + src/lib/input/input.ts | 5 ++- src/lib/select/select.ts | 3 ++ 7 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/lib/form-field/_form-field-theme.scss b/src/lib/form-field/_form-field-theme.scss index 8f475fd4f96f..980ad861c64b 100644 --- a/src/lib/form-field/_form-field-theme.scss +++ b/src/lib/form-field/_form-field-theme.scss @@ -14,7 +14,7 @@ // Placeholder colors. Required is used for the `*` star shown in the placeholder. $placeholder-color: mat-color($foreground, secondary-text); - $floating-placeholder-color: mat-color($primary); + $focused-placeholder-color: mat-color($primary); $required-placeholder-color: mat-color($accent); // Underline colors. @@ -32,7 +32,7 @@ } .mat-focused .mat-form-field-placeholder { - color: $floating-placeholder-color; + color: $focused-placeholder-color; &.mat-accent { color: $underline-color-accent; @@ -42,12 +42,9 @@ color: $underline-color-warn; } } - - .mat-form-field-autofill-float:-webkit-autofill + .mat-form-field-placeholder, - .mat-focused .mat-form-field-placeholder.mat-form-field-float { - .mat-form-field-required-marker { - color: $required-placeholder-color; - } + + .mat-focused .mat-form-field-required-marker { + color: $required-placeholder-color; } .mat-form-field-underline { @@ -78,7 +75,7 @@ color: $underline-color-warn; &.mat-accent, - &.mat-form-field-float .mat-form-field-required-marker { + .mat-form-field-required-marker { color: $underline-color-warn; } } @@ -178,8 +175,10 @@ border-top: $infix-margin-top solid transparent; } - .mat-form-field-autofill-float { - &:-webkit-autofill + .mat-form-field-placeholder-wrapper .mat-form-field-float { + .mat-form-field-can-float { + &.mat-form-field-should-float .mat-form-field-placeholder, + .mat-form-field-autofill-float:-webkit-autofill + .mat-form-field-placeholder-wrapper + .mat-form-field-placeholder { @include _mat-form-field-placeholder-floating( $subscript-font-scale, $infix-padding, $infix-margin-top); } @@ -192,13 +191,6 @@ .mat-form-field-placeholder { top: $infix-margin-top + $infix-padding; - - // Show the placeholder above the control when it's not empty, or focused. - &.mat-form-field-float:not(.mat-form-field-empty), - .mat-focused &.mat-form-field-float { - @include _mat-form-field-placeholder-floating($subscript-font-scale, - $infix-padding, $infix-margin-top); - } } .mat-form-field-underline { diff --git a/src/lib/form-field/form-field-control.ts b/src/lib/form-field/form-field-control.ts index 82d1b064ac12..811858101628 100644 --- a/src/lib/form-field/form-field-control.ts +++ b/src/lib/form-field/form-field-control.ts @@ -36,6 +36,9 @@ export abstract class MdFormFieldControl { /** Whether the control is empty. */ readonly empty: boolean; + /** Whether the `MdFormField` label should try to float. */ + readonly shouldPlaceholderFloat: boolean; + /** Whether the control is required. */ readonly required: boolean; diff --git a/src/lib/form-field/form-field.html b/src/lib/form-field/form-field.html index cfb7bfedab83..bad9f9aeb53b 100644 --- a/src/lib/form-field/form-field.html +++ b/src/lib/form-field/form-field.html @@ -12,8 +12,6 @@ [attr.for]="_control.id" [class.mat-empty]="_control.empty && !_shouldAlwaysFloat" [class.mat-form-field-empty]="_control.empty && !_shouldAlwaysFloat" - [class.mat-float]="_canPlaceholderFloat" - [class.mat-form-field-float]="_canPlaceholderFloat" [class.mat-accent]="color == 'accent'" [class.mat-warn]="color == 'warn'" *ngIf="_hasPlaceholder()"> diff --git a/src/lib/form-field/form-field.scss b/src/lib/form-field/form-field.scss index f74d6fdfba46..389083b262ea 100644 --- a/src/lib/form-field/form-field.scss +++ b/src/lib/form-field/form-field.scss @@ -63,23 +63,6 @@ $mat-form-field-underline-height: 1px !default; min-width: 0; } -// Pseudo-class for Chrome and Safari auto-fill to move the placeholder to the floating position. -// This is necessary because these browsers do not actually fire any events when a form auto-fill is -// occurring. Once the autofill is committed, a change event happen and the regular md-form-field -// classes take over to fulfill this behaviour. Assumes the autofill is non-empty. -.mat-form-field-autofill-float:-webkit-autofill + .mat-form-field-placeholder-wrapper { - // The control is still technically empty at this point, so we need to hide non-floating - // placeholders to prevent overlapping with the autofilled value. - .mat-form-field-placeholder { - display: none; - } - - .mat-form-field-float { - display: block; - transition: none; - } -} - // Used to hide the placeholder overflow on IE, since IE doesn't take transform into account when // determining overflow. .mat-form-field-placeholder-wrapper { @@ -122,12 +105,6 @@ $mat-form-field-underline-height: 1px !default; // Hide the placeholder initially, and only show it when it's floating or the control is empty. display: none; - &.mat-form-field-empty, - &.mat-form-field-float:not(.mat-form-field-empty), - .mat-focused &.mat-form-field-float { - display: block; - } - [dir='rtl'] & { transform-origin: 100% 0; left: auto; @@ -135,6 +112,28 @@ $mat-form-field-underline-height: 1px !default; } } +.mat-form-field-empty.mat-form-field-placeholder, +.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-placeholder { + display: block; +} + +// Pseudo-class for Chrome and Safari auto-fill to move the placeholder to the floating position. +// This is necessary because these browsers do not actually fire any events when a form auto-fill is +// occurring. Once the autofill is committed, a change event happen and the regular md-form-field +// classes take over to fulfill this behaviour. +.mat-form-field-autofill-float:-webkit-autofill + .mat-form-field-placeholder-wrapper + .mat-form-field-placeholder { + // The form field will be considered empty if it is autofilled, and therefore the placeholder will + // be shown. Therefore we need to override it to hidden... + display: none; + + // ...and re-show it only if it's able to float. + .mat-form-field-can-float & { + display: block; + transition: none; + } +} + // Disable the placeholder animation when the control is not empty (this prevents placeholder // animating up when the value is set programmatically). .mat-form-field-placeholder:not(.mat-form-field-empty) { diff --git a/src/lib/form-field/form-field.ts b/src/lib/form-field/form-field.ts index b7e43c7a9015..09b35790d886 100644 --- a/src/lib/form-field/form-field.ts +++ b/src/lib/form-field/form-field.ts @@ -71,6 +71,8 @@ let nextUniqueId = 0; 'class': 'mat-input-container mat-form-field', '[class.mat-input-invalid]': '_control.errorState', '[class.mat-form-field-invalid]': '_control.errorState', + '[class.mat-form-field-can-float]': '_canPlaceholderFloat', + '[class.mat-form-field-should-float]': '_control.shouldPlaceholderFloat || _shouldAlwaysFloat', '[class.mat-focused]': '_control.focused', '[class.mat-primary]': 'color == "primary"', '[class.mat-accent]': 'color == "accent"', diff --git a/src/lib/input/input.ts b/src/lib/input/input.ts index 0f0368e29489..93d19e688517 100644 --- a/src/lib/input/input.ts +++ b/src/lib/input/input.ts @@ -52,7 +52,7 @@ let nextUniqueId = 0; @Directive({ selector: `input[mdInput], textarea[mdInput], input[matInput], textarea[matInput]`, host: { - 'class': 'mat-input-element', + 'class': 'mat-input-element mat-form-field-autofill-float', // Native input properties that are overwritten by Angular inputs need to be synced with // the native input element. Otherwise property bindings for those don't work. '[attr.id]': 'id', @@ -280,6 +280,9 @@ export class MdInput implements MdFormFieldControl, OnChanges, OnDestroy, D !this._isBadInput(); } + // Implemented as part of MdFormFieldControl. + get shouldPlaceholderFloat(): boolean { return this.focused || !this.empty; } + // Implemented as part of MdFormFieldControl. setDescribedByIds(ids: string[]) { this._ariaDescribedby = ids.join(' '); } diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts index 1dde1c69d137..ef8a2ffecfa5 100644 --- a/src/lib/select/select.ts +++ b/src/lib/select/select.ts @@ -1170,6 +1170,9 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On this.focus(); this.open(); } + + // Implemented as part of MdFormFieldControl. + get shouldPlaceholderFloat() { return !this.empty; } } /** Clamps a value n between min and max values. */