From e8d99b75c736d64843bb3a8125fa2bd1ef90ca6d Mon Sep 17 00:00:00 2001 From: crisbeto Date: Mon, 8 Jan 2018 20:01:45 +0100 Subject: [PATCH 01/19] feat(form-field): implement hover state [Based on the spec](https://material.io/guidelines/components/text-fields.html#text-fields-states) form fields should have a hover state where the underline gets darkened while the user is hovering and gets replaced by the theme color after the focus the input. --- src/lib/form-field/_form-field-theme.scss | 21 ++++++++++++++------- src/lib/form-field/form-field.scss | 11 +++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/lib/form-field/_form-field-theme.scss b/src/lib/form-field/_form-field-theme.scss index ee21101bc024..ce0819f96397 100644 --- a/src/lib/form-field/_form-field-theme.scss +++ b/src/lib/form-field/_form-field-theme.scss @@ -19,6 +19,7 @@ // Underline colors. $underline-color: mat-color($foreground, divider, if($is-dark-theme, 0.7, 0.42)); + $underline-color-base: mat-color($foreground, divider, if($is-dark-theme, 1, 0.87)); $underline-color-accent: mat-color($accent); $underline-color-warn: mat-color($warn); $underline-focused-color: mat-color($primary); @@ -56,21 +57,27 @@ } .mat-form-field-ripple { - background-color: $underline-focused-color; + background-color: $underline-color-base; + } - &.mat-accent { - background-color: $underline-color-accent; - } + .mat-form-field.mat-focused { + .mat-form-field-ripple { + background-color: $underline-focused-color; - &.mat-warn { - background-color: $underline-color-warn; + &.mat-accent { + background-color: $underline-color-accent; + } + + &.mat-warn { + background-color: $underline-color-warn; + } } } // Styling for the error state of the form field. Note that while the same can be // achieved with the ng-* classes, we use this approach in order to ensure that the same // logic is used to style the error state and to show the error messages. - .mat-form-field-invalid { + .mat-form-field.mat-form-field-invalid { .mat-form-field-label { color: $underline-color-warn; diff --git a/src/lib/form-field/form-field.scss b/src/lib/form-field/form-field.scss index 974a46997586..0ef28dedf32b 100644 --- a/src/lib/form-field/form-field.scss +++ b/src/lib/form-field/form-field.scss @@ -195,6 +195,17 @@ $mat-form-field-default-infix-width: 180px !default; } } +// Note that we need this specific of a selector because we don't want +// the hover effect to show when the user hovers over the hints. +.mat-form-field:not(.mat-form-field-disabled) .mat-input-flex:hover ~ .mat-input-underline { + .mat-form-field-ripple { + visibility: visible; + opacity: 1; + transform: none; + transition: opacity 600ms $swift-ease-out-timing-function; + } +} + // Wrapper for the hints and error messages. .mat-form-field-subscript-wrapper { position: absolute; From 19feeb02273bef79ae4460f58f048362b5cbae32 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 11 Jan 2018 15:40:55 -0800 Subject: [PATCH 02/19] branch css logic --- src/demo-app/input/input-demo.scss | 1 + src/lib/form-field/_form-field-box-theme.scss | 24 +++++++++++++++++++ .../_form-field-standard-theme.scss | 15 ++++++++++++ src/lib/form-field/_form-field-theme.scss | 5 ++++ src/lib/form-field/form-field-box.scss | 14 +++++++++++ src/lib/form-field/form-field-standard.scss | 10 ++++++++ src/lib/form-field/form-field.ts | 13 +++++++++- 7 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/lib/form-field/_form-field-box-theme.scss create mode 100644 src/lib/form-field/_form-field-standard-theme.scss create mode 100644 src/lib/form-field/form-field-box.scss create mode 100644 src/lib/form-field/form-field-standard.scss diff --git a/src/demo-app/input/input-demo.scss b/src/demo-app/input/input-demo.scss index db8cb556622d..8bf4c17f27b5 100644 --- a/src/demo-app/input/input-demo.scss +++ b/src/demo-app/input/input-demo.scss @@ -3,6 +3,7 @@ } .demo-basic .mat-card-content { padding: 16px; + font-size: 16px; } .demo-full-width { width: 100%; diff --git a/src/lib/form-field/_form-field-box-theme.scss b/src/lib/form-field/_form-field-box-theme.scss new file mode 100644 index 000000000000..32d63f8f8d2c --- /dev/null +++ b/src/lib/form-field/_form-field-box-theme.scss @@ -0,0 +1,24 @@ +@import '../core/theming/palette'; +@import '../core/theming/theming'; +@import '../core/style/form-common'; +@import '../core/typography/typography-utils'; + + +// Theme styles that only apply to the box variant of the form-field. + +@mixin mat-form-field-box-theme($theme) { + $foreground: map-get($theme, foreground); + $is-dark-theme: map-get($theme, is-dark); + + $box-background: mat-color($foreground, base, if($is-dark-theme, 0.1, 0.06)); + + .mat-form-field-variant-box { + .mat-form-field-flex { + background-color: $box-background; + } + } +} + +@mixin mat-form-field-box-typography($config) { + +} diff --git a/src/lib/form-field/_form-field-standard-theme.scss b/src/lib/form-field/_form-field-standard-theme.scss new file mode 100644 index 000000000000..d59c94d41e1a --- /dev/null +++ b/src/lib/form-field/_form-field-standard-theme.scss @@ -0,0 +1,15 @@ +@import '../core/theming/palette'; +@import '../core/theming/theming'; +@import '../core/style/form-common'; +@import '../core/typography/typography-utils'; + + +// Theme styles that only apply to the standard variant of the form-field. + +@mixin mat-form-field-standard-theme($theme) { + +} + +@mixin mat-form-field-standard-typography($config) { + +} diff --git a/src/lib/form-field/_form-field-theme.scss b/src/lib/form-field/_form-field-theme.scss index ce0819f96397..e31331edae9c 100644 --- a/src/lib/form-field/_form-field-theme.scss +++ b/src/lib/form-field/_form-field-theme.scss @@ -2,6 +2,8 @@ @import '../core/theming/theming'; @import '../core/style/form-common'; @import '../core/typography/typography-utils'; +@import 'form-field-box-theme.scss'; +@import 'form-field-standard-theme.scss'; @mixin mat-form-field-theme($theme) { @@ -95,6 +97,9 @@ .mat-error { color: $underline-color-warn; } + + @include mat-form-field-standard-theme($theme); + @include mat-form-field-box-theme($theme); } // Used to make instances of the _mat-form-field-label-floating mixin negligibly different, diff --git a/src/lib/form-field/form-field-box.scss b/src/lib/form-field/form-field-box.scss new file mode 100644 index 000000000000..70a71a04a25d --- /dev/null +++ b/src/lib/form-field/form-field-box.scss @@ -0,0 +1,14 @@ +@import '../core/style/variables'; +@import '../core/style/vendor-prefixes'; + + +// Styles that only apply to the standard variant of the form-field. + +$mat-form-field-box-border-radius: 4px; + + +.mat-form-field-variant-box { + .mat-form-field-flex { + border-radius: $mat-form-field-box-border-radius; + } +} diff --git a/src/lib/form-field/form-field-standard.scss b/src/lib/form-field/form-field-standard.scss new file mode 100644 index 000000000000..3441727c2c42 --- /dev/null +++ b/src/lib/form-field/form-field-standard.scss @@ -0,0 +1,10 @@ +@import '../core/style/variables'; +@import '../core/style/vendor-prefixes'; + + +// Styles that only apply to the standard variant of the form-field. + + +.mat-form-field-variant-standard { + +} diff --git a/src/lib/form-field/form-field.ts b/src/lib/form-field/form-field.ts index e84da2d09ad3..f6ccd01e1eb5 100644 --- a/src/lib/form-field/form-field.ts +++ b/src/lib/form-field/form-field.ts @@ -56,10 +56,18 @@ let nextUniqueId = 0; // MatInput is a directive and can't have styles, so we need to include its styles here. // The MatInput styles are fairly minimal so it shouldn't be a big deal for people who // aren't using MatInput. - styleUrls: ['form-field.css', '../input/input.css'], + styleUrls: [ + 'form-field.css', + 'form-field-box.css', + 'form-field-standard.css', + '../input/input.css', + ], animations: [matFormFieldAnimations.transitionMessages], host: { 'class': 'mat-input-container mat-form-field', + '[class.mat-form-field-variant-standard]': 'variant == "standard"', + '[class.mat-form-field-variant-box]': 'variant == "box"', + '[class.mat-form-field-variant-outline]': 'variant == "outline"', '[class.mat-input-invalid]': '_control.errorState', '[class.mat-form-field-invalid]': '_control.errorState', '[class.mat-form-field-can-float]': '_canLabelFloat', @@ -86,6 +94,9 @@ let nextUniqueId = 0; export class MatFormField implements AfterViewInit, AfterContentInit, AfterContentChecked { private _labelOptions: LabelOptions; + /** The form-field style variant. */ + @Input() variant: 'standard' | 'box' | 'outline' = 'box'; + /** Color of the form field underline, based on the theme. */ @Input() color: 'primary' | 'accent' | 'warn' = 'primary'; From 116f18992a7a917c55e738a5a4e40b0f774d4041 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 11 Jan 2018 16:00:48 -0800 Subject: [PATCH 03/19] extract underline css into standard variant --- src/lib/form-field/form-field-standard.scss | 51 ++++++++++++++++++++ src/lib/form-field/form-field.scss | 53 --------------------- src/lib/form-field/form-field.ts | 2 +- 3 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/lib/form-field/form-field-standard.scss b/src/lib/form-field/form-field-standard.scss index 3441727c2c42..89bfb60601e9 100644 --- a/src/lib/form-field/form-field-standard.scss +++ b/src/lib/form-field/form-field-standard.scss @@ -4,7 +4,58 @@ // Styles that only apply to the standard variant of the form-field. +// The height of the underline. +$mat-form-field-underline-height: 1px !default; + .mat-form-field-variant-standard { + // The underline is what's shown under the control, its prefix and its suffix. + // The ripple is the blue animation coming on top of it. + .mat-form-field-underline { + position: absolute; + height: $mat-form-field-underline-height; + width: 100%; + + .mat-form-field-ripple { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: $mat-form-field-underline-height * 2; + transform-origin: 50%; + transform: scaleX(0.5); + opacity: 0; + transition: background-color $swift-ease-in-duration $swift-ease-in-timing-function; + } + } + + &.mat-form-field-disabled .mat-form-field-underline { + background-position: 0; + background-color: transparent; + } + + &.mat-form-field-invalid:not(.mat-focused) .mat-form-field-ripple { + height: $mat-form-field-underline-height; + } + + &.mat-focused, + &.mat-form-field-invalid { + .mat-form-field-ripple { + opacity: 1; + transform: scaleX(1); + transition: transform 300ms $swift-ease-out-timing-function, + opacity 100ms $swift-ease-out-timing-function, + background-color 300ms $swift-ease-out-timing-function; + } + } + // Note that we need this specific of a selector because we don't want + // the hover effect to show when the user hovers over the hints. + &:not(.mat-form-field-disabled) .mat-input-flex:hover ~ .mat-input-underline { + .mat-form-field-ripple { + opacity: 1; + transform: none; + transition: opacity 600ms $swift-ease-out-timing-function; + } + } } diff --git a/src/lib/form-field/form-field.scss b/src/lib/form-field/form-field.scss index 0ef28dedf32b..c659401e350f 100644 --- a/src/lib/form-field/form-field.scss +++ b/src/lib/form-field/form-field.scss @@ -4,8 +4,6 @@ // Min amount of space between start and end hint. $mat-form-field-hint-min-space: 1em !default; -// The height of the underline. -$mat-form-field-underline-height: 1px !default; // Infix stretches to fit the container, but naturally wants to be this wide. We set this in order // to have a a consistent natural size for the various types of controls that can go in a form // field. @@ -155,57 +153,6 @@ $mat-form-field-default-infix-width: 180px !default; transition: none; } -// The underline is what's shown under the control, its prefix and its suffix. -// The ripple is the blue animation coming on top of it. -.mat-form-field-underline { - position: absolute; - height: $mat-form-field-underline-height; - width: 100%; - - .mat-form-field-disabled & { - background-position: 0; - background-color: transparent; - } - - .mat-form-field-ripple { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: $mat-form-field-underline-height * 2; - transform-origin: 50%; - transform: scaleX(0.5); - visibility: hidden; - opacity: 0; - transition: background-color $swift-ease-in-duration $swift-ease-in-timing-function; - - .mat-form-field-invalid:not(.mat-focused) & { - height: $mat-form-field-underline-height; - } - - .mat-focused &, - .mat-form-field-invalid & { - visibility: visible; - opacity: 1; - transform: scaleX(1); - transition: transform 300ms $swift-ease-out-timing-function, - opacity 100ms $swift-ease-out-timing-function, - background-color 300ms $swift-ease-out-timing-function; - } - } -} - -// Note that we need this specific of a selector because we don't want -// the hover effect to show when the user hovers over the hints. -.mat-form-field:not(.mat-form-field-disabled) .mat-input-flex:hover ~ .mat-input-underline { - .mat-form-field-ripple { - visibility: visible; - opacity: 1; - transform: none; - transition: opacity 600ms $swift-ease-out-timing-function; - } -} - // Wrapper for the hints and error messages. .mat-form-field-subscript-wrapper { position: absolute; diff --git a/src/lib/form-field/form-field.ts b/src/lib/form-field/form-field.ts index f6ccd01e1eb5..691830448692 100644 --- a/src/lib/form-field/form-field.ts +++ b/src/lib/form-field/form-field.ts @@ -95,7 +95,7 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte private _labelOptions: LabelOptions; /** The form-field style variant. */ - @Input() variant: 'standard' | 'box' | 'outline' = 'box'; + @Input() variant: 'standard' | 'box' | 'outline' = 'standard'; /** Color of the form field underline, based on the theme. */ @Input() color: 'primary' | 'accent' | 'warn' = 'primary'; From 4e3356ec61071a8264f24bd27fa904c3d14cf866 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 11 Jan 2018 17:03:30 -0800 Subject: [PATCH 04/19] box variant underline --- src/demo-app/input/input-demo.html | 2 +- src/lib/form-field/_form-field-box-theme.scss | 13 ++++-- .../_form-field-standard-theme.scss | 16 +++++++- src/lib/form-field/_form-field-theme.scss | 9 ----- src/lib/form-field/form-field-box.scss | 21 ++++++++++ src/lib/form-field/form-field-standard.scss | 40 +++---------------- src/lib/form-field/form-field.scss | 36 +++++++++++++++++ src/lib/form-field/form-field.ts | 2 +- 8 files changed, 88 insertions(+), 51 deletions(-) diff --git a/src/demo-app/input/input-demo.html b/src/demo-app/input/input-demo.html index d61f52c99508..859d58ff38f2 100644 --- a/src/demo-app/input/input-demo.html +++ b/src/demo-app/input/input-demo.html @@ -38,7 +38,7 @@ - + diff --git a/src/lib/form-field/_form-field-box-theme.scss b/src/lib/form-field/_form-field-box-theme.scss index 32d63f8f8d2c..7643174d3925 100644 --- a/src/lib/form-field/_form-field-box-theme.scss +++ b/src/lib/form-field/_form-field-box-theme.scss @@ -11,14 +11,21 @@ $is-dark-theme: map-get($theme, is-dark); $box-background: mat-color($foreground, base, if($is-dark-theme, 0.1, 0.06)); + $underline-color: mat-color($foreground, divider, if($is-dark-theme, 0.7, 0.42)); .mat-form-field-variant-box { .mat-form-field-flex { background-color: $box-background; } - } -} -@mixin mat-form-field-box-typography($config) { + .mat-form-field-underline::before { + background-color: $underline-color; + } + &.mat-form-field-disabled .mat-form-field-underline::before { + background-color: transparent; + } + } } + +@mixin mat-form-field-box-typography($config) {} diff --git a/src/lib/form-field/_form-field-standard-theme.scss b/src/lib/form-field/_form-field-standard-theme.scss index d59c94d41e1a..dcd29c275b9c 100644 --- a/src/lib/form-field/_form-field-standard-theme.scss +++ b/src/lib/form-field/_form-field-standard-theme.scss @@ -6,10 +6,22 @@ // Theme styles that only apply to the standard variant of the form-field. + @mixin mat-form-field-standard-theme($theme) { + $foreground: map-get($theme, foreground); + $is-dark-theme: map-get($theme, is-dark); -} + $underline-color: mat-color($foreground, divider, if($is-dark-theme, 0.7, 0.42)); -@mixin mat-form-field-standard-typography($config) { + .mat-form-field-variant-standard { + .mat-form-field-underline { + background-color: $underline-color; + } + .mat-form-field-disabled .mat-form-field-underline { + @include mat-control-disabled-underline($underline-color); + } + } } + +@mixin mat-form-field-standard-typography($config) {} diff --git a/src/lib/form-field/_form-field-theme.scss b/src/lib/form-field/_form-field-theme.scss index e31331edae9c..7b1519bb7b27 100644 --- a/src/lib/form-field/_form-field-theme.scss +++ b/src/lib/form-field/_form-field-theme.scss @@ -20,7 +20,6 @@ $required-label-color: mat-color($accent); // Underline colors. - $underline-color: mat-color($foreground, divider, if($is-dark-theme, 0.7, 0.42)); $underline-color-base: mat-color($foreground, divider, if($is-dark-theme, 1, 0.87)); $underline-color-accent: mat-color($accent); $underline-color-warn: mat-color($warn); @@ -50,14 +49,6 @@ color: $required-label-color; } - .mat-form-field-underline { - background-color: $underline-color; - } - - .mat-form-field-disabled .mat-form-field-underline { - @include mat-control-disabled-underline($underline-color); - } - .mat-form-field-ripple { background-color: $underline-color-base; } diff --git a/src/lib/form-field/form-field-box.scss b/src/lib/form-field/form-field-box.scss index 70a71a04a25d..62372afdffd1 100644 --- a/src/lib/form-field/form-field-box.scss +++ b/src/lib/form-field/form-field-box.scss @@ -5,10 +5,31 @@ // Styles that only apply to the standard variant of the form-field. $mat-form-field-box-border-radius: 4px; +$mat-form-field-box-underline-height: 2px; .mat-form-field-variant-box { .mat-form-field-flex { border-radius: $mat-form-field-box-border-radius; } + + .mat-form-field-underline { + height: $mat-form-field-box-border-radius; + border-radius: 0 0 $mat-form-field-box-border-radius $mat-form-field-box-border-radius; + overflow: hidden; + } + + .mat-form-field-underline::before { + content: ''; + display: block; + position: absolute; + bottom: 0; + height: $mat-form-field-box-underline-height; + width: 100%; + } + + .mat-form-field-ripple { + bottom: 0; + height: $mat-form-field-box-underline-height; + } } diff --git a/src/lib/form-field/form-field-standard.scss b/src/lib/form-field/form-field-standard.scss index 89bfb60601e9..5d32fe626b18 100644 --- a/src/lib/form-field/form-field-standard.scss +++ b/src/lib/form-field/form-field-standard.scss @@ -12,21 +12,12 @@ $mat-form-field-underline-height: 1px !default; // The underline is what's shown under the control, its prefix and its suffix. // The ripple is the blue animation coming on top of it. .mat-form-field-underline { - position: absolute; height: $mat-form-field-underline-height; - width: 100%; - - .mat-form-field-ripple { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: $mat-form-field-underline-height * 2; - transform-origin: 50%; - transform: scaleX(0.5); - opacity: 0; - transition: background-color $swift-ease-in-duration $swift-ease-in-timing-function; - } + } + + .mat-form-field-ripple { + top: 0; + height: $mat-form-field-underline-height * 2; } &.mat-form-field-disabled .mat-form-field-underline { @@ -37,25 +28,4 @@ $mat-form-field-underline-height: 1px !default; &.mat-form-field-invalid:not(.mat-focused) .mat-form-field-ripple { height: $mat-form-field-underline-height; } - - &.mat-focused, - &.mat-form-field-invalid { - .mat-form-field-ripple { - opacity: 1; - transform: scaleX(1); - transition: transform 300ms $swift-ease-out-timing-function, - opacity 100ms $swift-ease-out-timing-function, - background-color 300ms $swift-ease-out-timing-function; - } - } - - // Note that we need this specific of a selector because we don't want - // the hover effect to show when the user hovers over the hints. - &:not(.mat-form-field-disabled) .mat-input-flex:hover ~ .mat-input-underline { - .mat-form-field-ripple { - opacity: 1; - transform: none; - transition: opacity 600ms $swift-ease-out-timing-function; - } - } } diff --git a/src/lib/form-field/form-field.scss b/src/lib/form-field/form-field.scss index c659401e350f..87b8cd9bd413 100644 --- a/src/lib/form-field/form-field.scss +++ b/src/lib/form-field/form-field.scss @@ -153,6 +153,42 @@ $mat-form-field-default-infix-width: 180px !default; transition: none; } +.mat-form-field-underline { + position: absolute; + width: 100%; +} + +.mat-form-field-ripple { + position: absolute; + left: 0; + width: 100%; + transform-origin: 50%; + transform: scaleX(0.5); + opacity: 0; + transition: background-color $swift-ease-in-duration $swift-ease-in-timing-function; +} + +.mat-form-field.mat-focused, +.mat-form-field.mat-form-field-invalid { + .mat-form-field-ripple { + opacity: 1; + transform: scaleX(1); + transition: transform 300ms $swift-ease-out-timing-function, + opacity 100ms $swift-ease-out-timing-function, + background-color 300ms $swift-ease-out-timing-function; + } +} + +// Note that we need this specific of a selector because we don't want +// the hover effect to show when the user hovers over the hints. +.mat-form-field:not(.mat-form-field-disabled) .mat-input-flex:hover ~ .mat-input-underline { + .mat-form-field-ripple { + opacity: 1; + transform: none; + transition: opacity 600ms $swift-ease-out-timing-function; + } +} + // Wrapper for the hints and error messages. .mat-form-field-subscript-wrapper { position: absolute; diff --git a/src/lib/form-field/form-field.ts b/src/lib/form-field/form-field.ts index 691830448692..f6ccd01e1eb5 100644 --- a/src/lib/form-field/form-field.ts +++ b/src/lib/form-field/form-field.ts @@ -95,7 +95,7 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte private _labelOptions: LabelOptions; /** The form-field style variant. */ - @Input() variant: 'standard' | 'box' | 'outline' = 'standard'; + @Input() variant: 'standard' | 'box' | 'outline' = 'box'; /** Color of the form field underline, based on the theme. */ @Input() color: 'primary' | 'accent' | 'warn' = 'primary'; From 358eb9fc960c2f696ff6a2660aa7f7ed0e7c4043 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Fri, 12 Jan 2018 10:32:11 -0800 Subject: [PATCH 05/19] box variant spacing --- src/lib/form-field/_form-field-box-theme.scss | 5 ++++ .../_form-field-standard-theme.scss | 1 - src/lib/form-field/_form-field-theme.scss | 9 ++++-- src/lib/form-field/form-field-box.scss | 28 +++++++++++++++++-- src/lib/form-field/form-field.scss | 4 +++ src/lib/select/select.scss | 5 ++++ 6 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/lib/form-field/_form-field-box-theme.scss b/src/lib/form-field/_form-field-box-theme.scss index 7643174d3925..3c3064ec3386 100644 --- a/src/lib/form-field/_form-field-box-theme.scss +++ b/src/lib/form-field/_form-field-box-theme.scss @@ -11,6 +11,7 @@ $is-dark-theme: map-get($theme, is-dark); $box-background: mat-color($foreground, base, if($is-dark-theme, 0.1, 0.06)); + $box-disabled-background: mat-color($foreground, base, if($is-dark-theme, 0.05, 0.03)); $underline-color: mat-color($foreground, divider, if($is-dark-theme, 0.7, 0.42)); .mat-form-field-variant-box { @@ -18,6 +19,10 @@ background-color: $box-background; } + &.mat-form-field-disabled .mat-form-field-flex { + background-color: $box-disabled-background; + } + .mat-form-field-underline::before { background-color: $underline-color; } diff --git a/src/lib/form-field/_form-field-standard-theme.scss b/src/lib/form-field/_form-field-standard-theme.scss index dcd29c275b9c..f2b8e431d791 100644 --- a/src/lib/form-field/_form-field-standard-theme.scss +++ b/src/lib/form-field/_form-field-standard-theme.scss @@ -6,7 +6,6 @@ // Theme styles that only apply to the standard variant of the form-field. - @mixin mat-form-field-standard-theme($theme) { $foreground: map-get($theme, foreground); $is-dark-theme: map-get($theme, is-dark); diff --git a/src/lib/form-field/_form-field-theme.scss b/src/lib/form-field/_form-field-theme.scss index 7b1519bb7b27..5b00a2025a94 100644 --- a/src/lib/form-field/_form-field-theme.scss +++ b/src/lib/form-field/_form-field-theme.scss @@ -6,6 +6,8 @@ @import 'form-field-standard-theme.scss'; +// Theme styles that apply to all variants of the form-field. + @mixin mat-form-field-theme($theme) { $primary: map-get($theme, primary); $accent: map-get($theme, accent); @@ -130,7 +132,7 @@ $dedupe: 0; $line-spacing: ($line-height - 1) / 2; // The padding on the infix. Mocks show half of the text size, but seem to measure from the edge // of the text itself, not the edge of the line; therefore we subtract off the line spacing. - $infix-padding: 0.5em - $line-spacing; + $infix-padding: 0.5em; // The margin applied to the form-field-infix to reserve space for the floating label. $infix-margin-top: 1em * $line-height * $subscript-font-scale; // Font size to use for the label and subscript text. @@ -142,7 +144,7 @@ $dedupe: 0; // text font size, so we need to divide by the scale factor to make it half of the original text // size. We again need to subtract off the line spacing since the mocks measure to the edge of the // text, not the edge of the line. - $subscript-margin-top: 0.5em / $subscript-font-scale - ($line-spacing * 2); + $subscript-margin-top: 0.5em / $subscript-font-scale; // The padding applied to the form-field-wrapper to reserve space for the subscript, since it's // absolutely positioned. This is a combination of the subscript's margin and line-height, but we // need to multiply by the subscript font scale factor since the wrapper has a larger font size. @@ -230,4 +232,7 @@ $dedupe: 0; // so we move it up by the padding amount (adjusted for the smaller font size); top: calc(100% - #{$wrapper-padding-bottom / $subscript-font-scale}); } + + @include mat-form-field-standard-typography($config); + @include mat-form-field-box-typography($config); } diff --git a/src/lib/form-field/form-field-box.scss b/src/lib/form-field/form-field-box.scss index 62372afdffd1..be8a67f7fe19 100644 --- a/src/lib/form-field/form-field-box.scss +++ b/src/lib/form-field/form-field-box.scss @@ -4,13 +4,33 @@ // Styles that only apply to the standard variant of the form-field. -$mat-form-field-box-border-radius: 4px; -$mat-form-field-box-underline-height: 2px; +// The border radius for the form field box. +$mat-form-field-box-border-radius: 4px !default; +// The height of the underline at the bottom of the form field box. +$mat-form-field-box-underline-height: 2px !default; +// The horizontal padding between the edge of the form field box and the start of the text. +$mat-form-field-box-side-padding: 1em !default; +// The vertical padding between the edge of the form field box and the start of the text as well as +// between the floating label and the value. +$mat-form-field-box-line-spacing: 0.5em !default; +// The scale of the subscript and floating label text w.r.t the value text. +$mat-form-field-box-subscript-font-scale: .75 !default; +// The horizontal padding between the edge of the subscript box and the start of the subscript text. +$mat-form-field-box-subscript-padding: + $mat-form-field-box-side-padding / $mat-form-field-box-subscript-font-scale; .mat-form-field-variant-box { .mat-form-field-flex { border-radius: $mat-form-field-box-border-radius; + padding: $mat-form-field-box-line-spacing $mat-form-field-box-side-padding 0 + $mat-form-field-box-side-padding; + } + + .mat-form-field-label { + // The perspective helps smooth out animations on Chrome and Firefox but isn't needed on IE. + transform: translateY(-50%) perspective(100px); + -ms-transform: translateY(-50%); } .mat-form-field-underline { @@ -32,4 +52,8 @@ $mat-form-field-box-underline-height: 2px; bottom: 0; height: $mat-form-field-box-underline-height; } + + .mat-form-field-subscript-wrapper { + padding: 0 $mat-form-field-box-subscript-padding; + } } diff --git a/src/lib/form-field/form-field.scss b/src/lib/form-field/form-field.scss index 87b8cd9bd413..cab856e51e41 100644 --- a/src/lib/form-field/form-field.scss +++ b/src/lib/form-field/form-field.scss @@ -2,6 +2,8 @@ @import '../core/style/vendor-prefixes'; +// Styles that apply to all variants of the form-field. + // Min amount of space between start and end hint. $mat-form-field-hint-min-space: 1em !default; // Infix stretches to fit the container, but naturally wants to be this wide. We set this in order @@ -33,6 +35,7 @@ $mat-form-field-default-infix-width: 180px !default; .mat-form-field-flex { display: inline-flex; align-items: baseline; + box-sizing: border-box; width: 100%; } @@ -192,6 +195,7 @@ $mat-form-field-default-infix-width: 180px !default; // Wrapper for the hints and error messages. .mat-form-field-subscript-wrapper { position: absolute; + box-sizing: border-box; width: 100%; overflow: hidden; // prevents multi-line errors from overlapping the control } diff --git a/src/lib/select/select.scss b/src/lib/select/select.scss index 7939c435dbd7..5057b6f3b916 100644 --- a/src/lib/select/select.scss +++ b/src/lib/select/select.scss @@ -45,6 +45,11 @@ $mat-select-placeholder-arrow-space: 2 * ($mat-select-arrow-size + $mat-select-a .mat-select-arrow-wrapper { display: table-cell; vertical-align: middle; + + // When used in a box variant form-field the arrow should be centered in the box. + .mat-form-field-variant-box & { + transform: translateY(-50%); + } } .mat-select-arrow { From dabdc278277cf9c2688f8bcb47023efda0c1543e Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Fri, 12 Jan 2018 11:41:20 -0800 Subject: [PATCH 06/19] add legacy variant --- .../form-field/_form-field-legacy-theme.scss | 123 ++++++++++++++++++ .../_form-field-standard-theme.scss | 2 +- src/lib/form-field/_form-field-theme.scss | 20 +-- src/lib/form-field/form-field-legacy.scss | 31 +++++ src/lib/form-field/form-field-standard.scss | 20 ++- src/lib/form-field/form-field.scss | 4 +- src/lib/form-field/form-field.ts | 5 +- 7 files changed, 185 insertions(+), 20 deletions(-) create mode 100644 src/lib/form-field/_form-field-legacy-theme.scss create mode 100644 src/lib/form-field/form-field-legacy.scss diff --git a/src/lib/form-field/_form-field-legacy-theme.scss b/src/lib/form-field/_form-field-legacy-theme.scss new file mode 100644 index 000000000000..d11a08764e97 --- /dev/null +++ b/src/lib/form-field/_form-field-legacy-theme.scss @@ -0,0 +1,123 @@ +@import '../core/theming/palette'; +@import '../core/theming/theming'; +@import '../core/style/form-common'; +@import '../core/typography/typography-utils'; + + +// Theme styles that only apply to the legacy variant of the form-field. + +@mixin mat-form-field-legacy-theme($theme) { + $foreground: map-get($theme, foreground); + $is-dark-theme: map-get($theme, is-dark); + + $underline-color: mat-color($foreground, divider, if($is-dark-theme, 0.7, 0.42)); + + .mat-form-field-variant-legacy { + .mat-form-field-underline { + background-color: $underline-color; + } + + &.mat-form-field-disabled .mat-form-field-underline { + @include mat-control-disabled-underline($underline-color); + } + } +} + +// Used to make instances of the _mat-form-field-label-floating mixin negligibly different, +// and prevent Google's CSS Optimizer from collapsing the declarations. This is needed because some +// of the selectors contain pseudo-classes not recognized in all browsers. If a browser encounters +// an unknown pseudo-class it will discard the entire rule set. +$mat-form-field-legacy-dedupe: 0; + +// Applies a floating label above the form field control itself. +@mixin _mat-form-field-label-floating($font-scale, $infix-padding, $infix-margin-top) { + // We use perspective to fix the text blurriness as described here: + // http://www.useragentman.com/blog/2014/05/04/fixing-typography-inside-of-2-d-css-transforms/ + // This results in a small jitter after the label floats on Firefox, which the + // translateZ fixes. + transform: translateY(-$infix-margin-top - $infix-padding) scale($font-scale) perspective(100px) + translateZ(0.001px + $mat-form-field-legacy-dedupe); + // The tricks above used to smooth out the animation on chrome and firefox actually make things + // worse on IE, so we don't include them in the IE version. + -ms-transform: translateY(-$infix-margin-top - $infix-padding + $mat-form-field-legacy-dedupe) + scale($font-scale); + + width: 100% / $font-scale + $mat-form-field-legacy-dedupe; + + $mat-form-field-legacy-dedupe: $mat-form-field-legacy-dedupe + 0.00001 !global; +} + +@mixin mat-form-field-legacy-typography($config) { + // The unit-less line-height from the font config. + $line-height: mat-line-height($config, input); + // The amount to scale the font for the floating label and subscript. + $subscript-font-scale: 0.75; + // The amount of space between the top of the line and the top of the actual text + // (as a fraction of the font-size). + $line-spacing: ($line-height - 1) / 2; + // The padding on the infix. Mocks show half of the text size, but seem to measure from the edge + // of the text itself, not the edge of the line; therefore we subtract off the line spacing. + $infix-padding: 0.5em - $line-spacing; + // The margin applied to the form-field-infix to reserve space for the floating label. + $infix-margin-top: 1em * $line-height * $subscript-font-scale; + // The space between the bottom of the .mat-form-field-flex area and the subscript wrapper. + // Mocks show half of the text size, but this margin is applied to an element with the subscript + // text font size, so we need to divide by the scale factor to make it half of the original text + // size. We again need to subtract off the line spacing since the mocks measure to the edge of the + // text, not the edge of the line. + $subscript-margin-top: 0.5em / $subscript-font-scale - ($line-spacing * 2); + // The padding applied to the form-field-wrapper to reserve space for the subscript, since it's + // absolutely positioned. This is a combination of the subscript's margin and line-height, but we + // need to multiply by the subscript font scale factor since the wrapper has a larger font size. + $wrapper-padding-bottom: ($subscript-margin-top + $line-height) * $subscript-font-scale; + + .mat-form-field-variant-legacy { + .mat-form-field-wrapper { + padding-bottom: $wrapper-padding-bottom; + } + + .mat-form-field-infix { + padding: $infix-padding 0; + } + + &.mat-form-field-can-float { + &.mat-form-field-should-float .mat-form-field-label, + .mat-input-server:focus + .mat-form-field-label-wrapper .mat-form-field-label { + @include _mat-form-field-label-floating( + $subscript-font-scale, $infix-padding, $infix-margin-top); + } + + .mat-form-field-autofill-control:-webkit-autofill + .mat-form-field-label-wrapper + .mat-form-field-label { + @include _mat-form-field-label-floating( + $subscript-font-scale, $infix-padding, $infix-margin-top); + } + + // Server-side rendered matInput with a label attribute but label not shown + // (used as a pure CSS stand-in for mat-form-field-should-float). + .mat-input-server[label]:not(:label-shown) + .mat-form-field-label-wrapper + .mat-form-field-label { + @include _mat-form-field-label-floating( + $subscript-font-scale, $infix-padding, $infix-margin-top); + } + } + + .mat-form-field-label { + top: $infix-margin-top + $infix-padding; + } + + .mat-form-field-underline { + // We want the underline to start at the end of the content box, not the padding box, + // so we move it up by the padding amount. + bottom: $wrapper-padding-bottom; + } + + .mat-form-field-subscript-wrapper { + margin-top: $subscript-margin-top; + + // We want the subscript to start at the end of the content box, not the padding box, + // so we move it up by the padding amount (adjusted for the smaller font size); + top: calc(100% - #{$wrapper-padding-bottom / $subscript-font-scale}); + } + } +} diff --git a/src/lib/form-field/_form-field-standard-theme.scss b/src/lib/form-field/_form-field-standard-theme.scss index f2b8e431d791..6afd317be516 100644 --- a/src/lib/form-field/_form-field-standard-theme.scss +++ b/src/lib/form-field/_form-field-standard-theme.scss @@ -17,7 +17,7 @@ background-color: $underline-color; } - .mat-form-field-disabled .mat-form-field-underline { + &.mat-form-field-disabled .mat-form-field-underline { @include mat-control-disabled-underline($underline-color); } } diff --git a/src/lib/form-field/_form-field-theme.scss b/src/lib/form-field/_form-field-theme.scss index 5b00a2025a94..382d51d849ab 100644 --- a/src/lib/form-field/_form-field-theme.scss +++ b/src/lib/form-field/_form-field-theme.scss @@ -3,6 +3,7 @@ @import '../core/style/form-common'; @import '../core/typography/typography-utils'; @import 'form-field-box-theme.scss'; +@import 'form-field-legacy-theme.scss'; @import 'form-field-standard-theme.scss'; @@ -91,6 +92,7 @@ color: $underline-color-warn; } + @include mat-form-field-legacy-theme($theme); @include mat-form-field-standard-theme($theme); @include mat-form-field-box-theme($theme); } @@ -99,7 +101,7 @@ // and prevent Google's CSS Optimizer from collapsing the declarations. This is needed because some // of the selectors contain pseudo-classes not recognized in all browsers. If a browser encounters // an unknown pseudo-class it will discard the entire rule set. -$dedupe: 0; +$mat-form-field-dedupe: 0; // Applies a floating label above the form field control itself. @mixin _mat-form-field-label-floating($font-scale, $infix-padding, $infix-margin-top) { @@ -108,14 +110,15 @@ $dedupe: 0; // This results in a small jitter after the label floats on Firefox, which the // translateZ fixes. transform: translateY(-$infix-margin-top - $infix-padding) scale($font-scale) perspective(100px) - translateZ(0.001px + $dedupe); + translateZ(0.001px + $mat-form-field-dedupe); // The tricks above used to smooth out the animation on chrome and firefox actually make things // worse on IE, so we don't include them in the IE version. - -ms-transform: translateY(-$infix-margin-top - $infix-padding + $dedupe) scale($font-scale); + -ms-transform: translateY(-$infix-margin-top - $infix-padding + $mat-form-field-dedupe) + scale($font-scale); - width: 100% / $font-scale + $dedupe; + width: 100% / $font-scale + $mat-form-field-dedupe; - $dedupe: $dedupe + 0.00001 !global; + $mat-form-field-dedupe: $mat-form-field-dedupe + 0.00001 !global; } @mixin mat-form-field-typography($config) { @@ -130,8 +133,7 @@ $dedupe: 0; // The amount of space between the top of the line and the top of the actual text // (as a fraction of the font-size). $line-spacing: ($line-height - 1) / 2; - // The padding on the infix. Mocks show half of the text size, but seem to measure from the edge - // of the text itself, not the edge of the line; therefore we subtract off the line spacing. + // The padding on the infix. Mocks show half of the text size. $infix-padding: 0.5em; // The margin applied to the form-field-infix to reserve space for the floating label. $infix-margin-top: 1em * $line-height * $subscript-font-scale; @@ -142,8 +144,7 @@ $dedupe: 0; // The space between the bottom of the .mat-form-field-flex area and the subscript wrapper. // Mocks show half of the text size, but this margin is applied to an element with the subscript // text font size, so we need to divide by the scale factor to make it half of the original text - // size. We again need to subtract off the line spacing since the mocks measure to the edge of the - // text, not the edge of the line. + // size. $subscript-margin-top: 0.5em / $subscript-font-scale; // The padding applied to the form-field-wrapper to reserve space for the subscript, since it's // absolutely positioned. This is a combination of the subscript's margin and line-height, but we @@ -233,6 +234,7 @@ $dedupe: 0; top: calc(100% - #{$wrapper-padding-bottom / $subscript-font-scale}); } + @include mat-form-field-legacy-typography($config); @include mat-form-field-standard-typography($config); @include mat-form-field-box-typography($config); } diff --git a/src/lib/form-field/form-field-legacy.scss b/src/lib/form-field/form-field-legacy.scss new file mode 100644 index 000000000000..e07a002d146c --- /dev/null +++ b/src/lib/form-field/form-field-legacy.scss @@ -0,0 +1,31 @@ +@import '../core/style/variables'; +@import '../core/style/vendor-prefixes'; + + +// Styles that only apply to the legacy variant of the form-field. + +// The height of the underline. +$mat-form-field-legacy-underline-height: 1px !default; + + +.mat-form-field-variant-legacy { + // The underline is what's shown under the control, its prefix and its suffix. + // The ripple is the blue animation coming on top of it. + .mat-form-field-underline { + height: $mat-form-field-legacy-underline-height; + } + + .mat-form-field-ripple { + top: 0; + height: $mat-form-field-legacy-underline-height * 2; + } + + &.mat-form-field-disabled .mat-form-field-underline { + background-position: 0; + background-color: transparent; + } + + &.mat-form-field-invalid:not(.mat-focused) .mat-form-field-ripple { + height: $mat-form-field-legacy-underline-height; + } +} diff --git a/src/lib/form-field/form-field-standard.scss b/src/lib/form-field/form-field-standard.scss index 5d32fe626b18..31f670512287 100644 --- a/src/lib/form-field/form-field-standard.scss +++ b/src/lib/form-field/form-field-standard.scss @@ -5,27 +5,33 @@ // Styles that only apply to the standard variant of the form-field. // The height of the underline. -$mat-form-field-underline-height: 1px !default; +$mat-form-field-standard-underline-height: 1px !default; +// The bottom margin of the underline (used to push it up to align with box variant underline). +$mat-form-field-standard-underline-margin-bottom: 1px !default; +// The padding between the top of the form field and the label text (used to align the standard +// form field with the box variant). +$mat-form-field-standard-padding-top: .5em !default; .mat-form-field-variant-standard { + .mat-form-field-flex { + padding-top: $mat-form-field-standard-padding-top; + } + // The underline is what's shown under the control, its prefix and its suffix. // The ripple is the blue animation coming on top of it. .mat-form-field-underline { - height: $mat-form-field-underline-height; + height: $mat-form-field-standard-underline-height; + margin-bottom: $mat-form-field-standard-underline-margin-bottom; } .mat-form-field-ripple { top: 0; - height: $mat-form-field-underline-height * 2; + height: $mat-form-field-standard-underline-height * 2; } &.mat-form-field-disabled .mat-form-field-underline { background-position: 0; background-color: transparent; } - - &.mat-form-field-invalid:not(.mat-focused) .mat-form-field-ripple { - height: $mat-form-field-underline-height; - } } diff --git a/src/lib/form-field/form-field.scss b/src/lib/form-field/form-field.scss index cab856e51e41..e6c7c2dda646 100644 --- a/src/lib/form-field/form-field.scss +++ b/src/lib/form-field/form-field.scss @@ -159,6 +159,8 @@ $mat-form-field-default-infix-width: 180px !default; .mat-form-field-underline { position: absolute; width: 100%; + // Need this so that the underline doesn't block the hover effect. + pointer-events: none; } .mat-form-field-ripple { @@ -184,7 +186,7 @@ $mat-form-field-default-infix-width: 180px !default; // Note that we need this specific of a selector because we don't want // the hover effect to show when the user hovers over the hints. -.mat-form-field:not(.mat-form-field-disabled) .mat-input-flex:hover ~ .mat-input-underline { +.mat-form-field:not(.mat-form-field-disabled) .mat-form-field-flex:hover ~ .mat-form-field-underline { .mat-form-field-ripple { opacity: 1; transform: none; diff --git a/src/lib/form-field/form-field.ts b/src/lib/form-field/form-field.ts index f6ccd01e1eb5..f80cd8aa17dc 100644 --- a/src/lib/form-field/form-field.ts +++ b/src/lib/form-field/form-field.ts @@ -59,6 +59,7 @@ let nextUniqueId = 0; styleUrls: [ 'form-field.css', 'form-field-box.css', + 'form-field-legacy.css', 'form-field-standard.css', '../input/input.css', ], @@ -67,7 +68,7 @@ let nextUniqueId = 0; 'class': 'mat-input-container mat-form-field', '[class.mat-form-field-variant-standard]': 'variant == "standard"', '[class.mat-form-field-variant-box]': 'variant == "box"', - '[class.mat-form-field-variant-outline]': 'variant == "outline"', + '[class.mat-form-field-variant-legacy]': 'variant == "legacy"', '[class.mat-input-invalid]': '_control.errorState', '[class.mat-form-field-invalid]': '_control.errorState', '[class.mat-form-field-can-float]': '_canLabelFloat', @@ -95,7 +96,7 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte private _labelOptions: LabelOptions; /** The form-field style variant. */ - @Input() variant: 'standard' | 'box' | 'outline' = 'box'; + @Input() variant: 'legacy' | 'standard' | 'box' = 'standard'; /** Color of the form field underline, based on the theme. */ @Input() color: 'primary' | 'accent' | 'warn' = 'primary'; From 3691d9b923b14cb93adc06618193f558c01cab6d Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Fri, 12 Jan 2018 14:55:09 -0800 Subject: [PATCH 07/19] fix select ellipsis --- src/lib/form-field/form-field.ts | 2 +- src/lib/select/select.scss | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/form-field/form-field.ts b/src/lib/form-field/form-field.ts index f80cd8aa17dc..24524d6a16b4 100644 --- a/src/lib/form-field/form-field.ts +++ b/src/lib/form-field/form-field.ts @@ -96,7 +96,7 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte private _labelOptions: LabelOptions; /** The form-field style variant. */ - @Input() variant: 'legacy' | 'standard' | 'box' = 'standard'; + @Input() variant: 'legacy' | 'standard' | 'box' = 'legacy'; /** Color of the form field underline, based on the theme. */ @Input() color: 'primary' | 'accent' | 'warn' = 'primary'; diff --git a/src/lib/select/select.scss b/src/lib/select/select.scss index 5057b6f3b916..12a6d82324e6 100644 --- a/src/lib/select/select.scss +++ b/src/lib/select/select.scss @@ -105,5 +105,7 @@ $mat-select-placeholder-arrow-space: 2 * ($mat-select-arrow-size + $mat-select-a // Remove the transition to prevent the placeholder // from overlapping when the label comes back down. transition: none; + // Prevents the '...' from showing on the parent element. + display: block; } } From c857be2deb88f7b9182414cd00c332030e9896f2 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Fri, 12 Jan 2018 15:06:32 -0800 Subject: [PATCH 08/19] move hover state changes out of legacy variant --- src/demo-app/input/input-demo.html | 2 +- src/demo-app/input/input-demo.scss | 1 - src/lib/form-field/form-field-standard.scss | 10 ++++++++++ src/lib/form-field/form-field.scss | 10 ---------- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/demo-app/input/input-demo.html b/src/demo-app/input/input-demo.html index 859d58ff38f2..d61f52c99508 100644 --- a/src/demo-app/input/input-demo.html +++ b/src/demo-app/input/input-demo.html @@ -38,7 +38,7 @@ - + diff --git a/src/demo-app/input/input-demo.scss b/src/demo-app/input/input-demo.scss index 8bf4c17f27b5..db8cb556622d 100644 --- a/src/demo-app/input/input-demo.scss +++ b/src/demo-app/input/input-demo.scss @@ -3,7 +3,6 @@ } .demo-basic .mat-card-content { padding: 16px; - font-size: 16px; } .demo-full-width { width: 100%; diff --git a/src/lib/form-field/form-field-standard.scss b/src/lib/form-field/form-field-standard.scss index 31f670512287..1858b5d1c858 100644 --- a/src/lib/form-field/form-field-standard.scss +++ b/src/lib/form-field/form-field-standard.scss @@ -34,4 +34,14 @@ $mat-form-field-standard-padding-top: .5em !default; background-position: 0; background-color: transparent; } + + // Note that we need this specific of a selector because we don't want + // the hover effect to show when the user hovers over the hints. + .mat-form-field:not(.mat-form-field-disabled) .mat-form-field-flex:hover ~ .mat-form-field-underline { + .mat-form-field-ripple { + opacity: 1; + transform: none; + transition: opacity 600ms $swift-ease-out-timing-function; + } + } } diff --git a/src/lib/form-field/form-field.scss b/src/lib/form-field/form-field.scss index e6c7c2dda646..ed44353b5f3e 100644 --- a/src/lib/form-field/form-field.scss +++ b/src/lib/form-field/form-field.scss @@ -184,16 +184,6 @@ $mat-form-field-default-infix-width: 180px !default; } } -// Note that we need this specific of a selector because we don't want -// the hover effect to show when the user hovers over the hints. -.mat-form-field:not(.mat-form-field-disabled) .mat-form-field-flex:hover ~ .mat-form-field-underline { - .mat-form-field-ripple { - opacity: 1; - transform: none; - transition: opacity 600ms $swift-ease-out-timing-function; - } -} - // Wrapper for the hints and error messages. .mat-form-field-subscript-wrapper { position: absolute; From 024a07031243b11f2dab62981202e8b163a9d7d9 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Fri, 12 Jan 2018 15:21:46 -0800 Subject: [PATCH 09/19] add variants section to input demo --- src/demo-app/input/input-demo.html | 47 +++++++++++++++++++++ src/demo-app/input/input-demo.ts | 4 ++ src/lib/form-field/form-field-box.scss | 10 +++++ src/lib/form-field/form-field-standard.scss | 2 +- 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/demo-app/input/input-demo.html b/src/demo-app/input/input-demo.html index d61f52c99508..e7ea8f9c9935 100644 --- a/src/demo-app/input/input-demo.html +++ b/src/demo-app/input/input-demo.html @@ -526,3 +526,50 @@

<textarea> with ngModel

+ + + Variants + + + + This field is required + Please type something here + + + + + This field is required + Please type something here + + + + + This field is required + Please type something here + + + + + + +
+ + + This field is required + Please type something here + + + + + This field is required + Please type something here + + + + + This field is required + Please type something here + +
+
+
diff --git a/src/demo-app/input/input-demo.ts b/src/demo-app/input/input-demo.ts index 67cc69667381..4ea26d9cba27 100644 --- a/src/demo-app/input/input-demo.ts +++ b/src/demo-app/input/input-demo.ts @@ -52,6 +52,10 @@ export class InputDemo { delayedFormControl = new FormControl(''); model = 'hello'; + legacyVariant: string; + standardVariant: string; + boxVariant: string; + constructor() { setTimeout(() => this.delayedFormControl.setValue('hello'), 100); } diff --git a/src/lib/form-field/form-field-box.scss b/src/lib/form-field/form-field-box.scss index be8a67f7fe19..534019e57c42 100644 --- a/src/lib/form-field/form-field-box.scss +++ b/src/lib/form-field/form-field-box.scss @@ -53,6 +53,16 @@ $mat-form-field-box-subscript-padding: height: $mat-form-field-box-underline-height; } + // Note that we need this specific of a selector because we don't want + // the hover effect to show when the user hovers over the hints. + &:not(.mat-form-field-disabled) .mat-form-field-flex:hover ~ .mat-form-field-underline { + .mat-form-field-ripple { + opacity: 1; + transform: none; + transition: opacity 600ms $swift-ease-out-timing-function; + } + } + .mat-form-field-subscript-wrapper { padding: 0 $mat-form-field-box-subscript-padding; } diff --git a/src/lib/form-field/form-field-standard.scss b/src/lib/form-field/form-field-standard.scss index 1858b5d1c858..920c911979cd 100644 --- a/src/lib/form-field/form-field-standard.scss +++ b/src/lib/form-field/form-field-standard.scss @@ -37,7 +37,7 @@ $mat-form-field-standard-padding-top: .5em !default; // Note that we need this specific of a selector because we don't want // the hover effect to show when the user hovers over the hints. - .mat-form-field:not(.mat-form-field-disabled) .mat-form-field-flex:hover ~ .mat-form-field-underline { + &:not(.mat-form-field-disabled) .mat-form-field-flex:hover ~ .mat-form-field-underline { .mat-form-field-ripple { opacity: 1; transform: none; From af21801c50cceb683b2f0db36711151ec970aad6 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Tue, 16 Jan 2018 10:32:51 -0800 Subject: [PATCH 10/19] use filter/backface-visibility to address label jumpiness --- src/lib/form-field/_form-field-legacy-theme.scss | 8 ++++---- src/lib/form-field/_form-field-theme.scss | 16 +++++----------- src/lib/form-field/form-field-box.scss | 6 ++---- src/lib/form-field/form-field-legacy.scss | 11 +++++++++++ src/lib/form-field/form-field.scss | 10 ++++++---- 5 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/lib/form-field/_form-field-legacy-theme.scss b/src/lib/form-field/_form-field-legacy-theme.scss index d11a08764e97..e8fd48792816 100644 --- a/src/lib/form-field/_form-field-legacy-theme.scss +++ b/src/lib/form-field/_form-field-legacy-theme.scss @@ -30,7 +30,7 @@ $mat-form-field-legacy-dedupe: 0; // Applies a floating label above the form field control itself. -@mixin _mat-form-field-label-floating($font-scale, $infix-padding, $infix-margin-top) { +@mixin _mat-form-field-legacy-label-floating($font-scale, $infix-padding, $infix-margin-top) { // We use perspective to fix the text blurriness as described here: // http://www.useragentman.com/blog/2014/05/04/fixing-typography-inside-of-2-d-css-transforms/ // This results in a small jitter after the label floats on Firefox, which the @@ -83,13 +83,13 @@ $mat-form-field-legacy-dedupe: 0; &.mat-form-field-can-float { &.mat-form-field-should-float .mat-form-field-label, .mat-input-server:focus + .mat-form-field-label-wrapper .mat-form-field-label { - @include _mat-form-field-label-floating( + @include _mat-form-field-legacy-label-floating( $subscript-font-scale, $infix-padding, $infix-margin-top); } .mat-form-field-autofill-control:-webkit-autofill + .mat-form-field-label-wrapper .mat-form-field-label { - @include _mat-form-field-label-floating( + @include _mat-form-field-legacy-label-floating( $subscript-font-scale, $infix-padding, $infix-margin-top); } @@ -97,7 +97,7 @@ $mat-form-field-legacy-dedupe: 0; // (used as a pure CSS stand-in for mat-form-field-should-float). .mat-input-server[label]:not(:label-shown) + .mat-form-field-label-wrapper .mat-form-field-label { - @include _mat-form-field-label-floating( + @include _mat-form-field-legacy-label-floating( $subscript-font-scale, $infix-padding, $infix-margin-top); } } diff --git a/src/lib/form-field/_form-field-theme.scss b/src/lib/form-field/_form-field-theme.scss index 382d51d849ab..91c24394107b 100644 --- a/src/lib/form-field/_form-field-theme.scss +++ b/src/lib/form-field/_form-field-theme.scss @@ -105,19 +105,13 @@ $mat-form-field-dedupe: 0; // Applies a floating label above the form field control itself. @mixin _mat-form-field-label-floating($font-scale, $infix-padding, $infix-margin-top) { - // We use perspective to fix the text blurriness as described here: - // http://www.useragentman.com/blog/2014/05/04/fixing-typography-inside-of-2-d-css-transforms/ - // This results in a small jitter after the label floats on Firefox, which the - // translateZ fixes. - transform: translateY(-$infix-margin-top - $infix-padding) scale($font-scale) perspective(100px) - translateZ(0.001px + $mat-form-field-dedupe); - // The tricks above used to smooth out the animation on chrome and firefox actually make things - // worse on IE, so we don't include them in the IE version. - -ms-transform: translateY(-$infix-margin-top - $infix-padding + $mat-form-field-dedupe) - scale($font-scale); - + transform: translateY(-$infix-margin-top - $infix-padding + $mat-form-field-dedupe) + scale($font-scale); width: 100% / $font-scale + $mat-form-field-dedupe; + // Prevent text bluriness when label is floating. + backface-visibility: initial; + $mat-form-field-dedupe: $mat-form-field-dedupe + 0.00001 !global; } diff --git a/src/lib/form-field/form-field-box.scss b/src/lib/form-field/form-field-box.scss index 534019e57c42..a07886f3ed26 100644 --- a/src/lib/form-field/form-field-box.scss +++ b/src/lib/form-field/form-field-box.scss @@ -2,7 +2,7 @@ @import '../core/style/vendor-prefixes'; -// Styles that only apply to the standard variant of the form-field. +// Styles that only apply to the box variant of the form-field. // The border radius for the form field box. $mat-form-field-box-border-radius: 4px !default; @@ -28,9 +28,7 @@ $mat-form-field-box-subscript-padding: } .mat-form-field-label { - // The perspective helps smooth out animations on Chrome and Firefox but isn't needed on IE. - transform: translateY(-50%) perspective(100px); - -ms-transform: translateY(-50%); + transform: translateY(-50%); } .mat-form-field-underline { diff --git a/src/lib/form-field/form-field-legacy.scss b/src/lib/form-field/form-field-legacy.scss index e07a002d146c..4c1f3c8ad5b8 100644 --- a/src/lib/form-field/form-field-legacy.scss +++ b/src/lib/form-field/form-field-legacy.scss @@ -9,6 +9,17 @@ $mat-form-field-legacy-underline-height: 1px !default; .mat-form-field-variant-legacy { + .mat-form-field-label-wrapper { + filter: initial; + } + + .mat-form-field-label { + backface-visibility: initial; + + transform: perspective(100px); + -ms-transform: none; + } + // The underline is what's shown under the control, its prefix and its suffix. // The ripple is the blue animation coming on top of it. .mat-form-field-underline { diff --git a/src/lib/form-field/form-field.scss b/src/lib/form-field/form-field.scss index ed44353b5f3e..d664b4296765 100644 --- a/src/lib/form-field/form-field.scss +++ b/src/lib/form-field/form-field.scss @@ -78,6 +78,9 @@ $mat-form-field-default-infix-width: 180px !default; height: 100%; overflow: hidden; pointer-events: none; // We shouldn't catch mouse events (let them through). + + // Helps prevent text jumpiness when transforming the label. + filter: blur(0); } // The label itself. This is invisible unless it is. The logic to show it is @@ -97,10 +100,6 @@ $mat-form-field-default-infix-width: 180px !default; text-overflow: ellipsis; overflow: hidden; - // The perspective helps smooth out animations on Chrome and Firefox but isn't needed on IE. - transform: perspective(100px); - -ms-transform: none; - transform-origin: 0 0; transition: transform $swift-ease-out-duration $swift-ease-out-timing-function, color $swift-ease-out-duration $swift-ease-out-timing-function, @@ -109,6 +108,9 @@ $mat-form-field-default-infix-width: 180px !default; // Hide the label initially, and only show it when it's floating or the control is empty. display: none; + // Helps prevent text jumpiness when transforming the label. + backface-visibility: hidden; + [dir='rtl'] & { transform-origin: 100% 0; left: auto; From ec76aa56baca2d9bccf2b2942b2451f7ff2e25a7 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Tue, 16 Jan 2018 10:38:24 -0800 Subject: [PATCH 11/19] address comments --- src/lib/form-field/form-field.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/lib/form-field/form-field.ts b/src/lib/form-field/form-field.ts index 24524d6a16b4..f618f15ff182 100644 --- a/src/lib/form-field/form-field.ts +++ b/src/lib/form-field/form-field.ts @@ -7,8 +7,6 @@ */ import {coerceBooleanProperty} from '@angular/cdk/coercion'; -import {take} from 'rxjs/operators/take'; -import {startWith} from 'rxjs/operators/startWith'; import { AfterContentChecked, AfterContentInit, @@ -26,9 +24,12 @@ import { ViewChild, ViewEncapsulation, } from '@angular/core'; -import {FloatLabelType, MAT_LABEL_GLOBAL_OPTIONS, LabelOptions} from '@angular/material/core'; +import {FloatLabelType, LabelOptions, MAT_LABEL_GLOBAL_OPTIONS} from '@angular/material/core'; import {fromEvent} from 'rxjs/observable/fromEvent'; +import {startWith} from 'rxjs/operators/startWith'; +import {take} from 'rxjs/operators/take'; import {MatError} from './error'; +import {matFormFieldAnimations} from './form-field-animations'; import {MatFormFieldControl} from './form-field-control'; import { getMatFormFieldDuplicatedHintError, @@ -36,16 +37,18 @@ import { getMatFormFieldPlaceholderConflictError, } from './form-field-errors'; import {MatHint} from './hint'; -import {MatPlaceholder} from './placeholder'; import {MatLabel} from './label'; +import {MatPlaceholder} from './placeholder'; import {MatPrefix} from './prefix'; import {MatSuffix} from './suffix'; -import {matFormFieldAnimations} from './form-field-animations'; let nextUniqueId = 0; +export type MatFormFieldVariant = 'legacy' | 'standard' | 'box'; + + /** Container for form controls that applies Material Design styling and behavior. */ @Component({ moduleId: module.id, @@ -96,7 +99,7 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte private _labelOptions: LabelOptions; /** The form-field style variant. */ - @Input() variant: 'legacy' | 'standard' | 'box' = 'legacy'; + @Input() variant: MatFormFieldVariant = 'legacy'; /** Color of the form field underline, based on the theme. */ @Input() color: 'primary' | 'accent' | 'warn' = 'primary'; From bef4ded8041c3c9cdd2d1814e7355d428b588b26 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Wed, 17 Jan 2018 14:29:43 -0800 Subject: [PATCH 12/19] fix box variant text fuzziness --- src/lib/form-field/_form-field-box-theme.scss | 62 ++++++++++++++++++- src/lib/form-field/_form-field-theme.scss | 3 - src/lib/form-field/form-field-box.scss | 4 -- 3 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/lib/form-field/_form-field-box-theme.scss b/src/lib/form-field/_form-field-box-theme.scss index 3c3064ec3386..757ae08676d9 100644 --- a/src/lib/form-field/_form-field-box-theme.scss +++ b/src/lib/form-field/_form-field-box-theme.scss @@ -33,4 +33,64 @@ } } -@mixin mat-form-field-box-typography($config) {} +// Used to make instances of the _mat-form-field-label-floating mixin negligibly different, +// and prevent Google's CSS Optimizer from collapsing the declarations. This is needed because some +// of the selectors contain pseudo-classes not recognized in all browsers. If a browser encounters +// an unknown pseudo-class it will discard the entire rule set. +$mat-form-field-box-dedupe: 0; + +// Applies a floating label above the form field control itself. +@mixin _mat-form-field-box-label-floating($font-scale, $infix-padding, $infix-margin-top) { + transform: translateY(-$infix-margin-top - $infix-padding + $mat-form-field-box-dedupe) + scale($font-scale); + width: 100% / $font-scale + $mat-form-field-box-dedupe; + + // Prevent text bluriness when label is floating. + backface-visibility: initial; + + $mat-form-field-box-dedupe: $mat-form-field-box-dedupe + 0.00001 !global; +} + +@mixin mat-form-field-box-typography($config) { + // The unit-less line-height from the font config. + $line-height: mat-line-height($config, input); + // The amount to scale the font for the floating label and subscript. + $subscript-font-scale: 0.75; + // The padding on the infix. Mocks show half of the text size. + $infix-padding: 0.5em; + // The margin applied to the form-field-infix to reserve space for the floating label. + $infix-margin-top: 1em * $line-height * $subscript-font-scale; + // The amount we offset the label in the box variant. + $box-variant-label-offset: -0.5em * $line-height; + + .mat-form-field-variant-box { + .mat-form-field-label { + margin-top: $box-variant-label-offset; + } + + &.mat-form-field-can-float { + &.mat-form-field-should-float .mat-form-field-label, + .mat-input-server:focus + .mat-form-field-label-wrapper .mat-form-field-label { + @include _mat-form-field-label-floating( + $subscript-font-scale, $infix-padding + $box-variant-label-offset, + $infix-margin-top); + } + + .mat-form-field-autofill-control:-webkit-autofill + .mat-form-field-label-wrapper + .mat-form-field-label { + @include _mat-form-field-label-floating( + $subscript-font-scale, $infix-padding + $box-variant-label-offset, + $infix-margin-top); + } + + // Server-side rendered matInput with a label attribute but label not shown + // (used as a pure CSS stand-in for mat-form-field-should-float). + .mat-input-server[label]:not(:label-shown) + .mat-form-field-label-wrapper + .mat-form-field-label { + @include _mat-form-field-label-floating( + $subscript-font-scale, $infix-padding + $box-variant-label-offset, + $infix-margin-top); + } + } + } +} diff --git a/src/lib/form-field/_form-field-theme.scss b/src/lib/form-field/_form-field-theme.scss index 91c24394107b..1514e008472f 100644 --- a/src/lib/form-field/_form-field-theme.scss +++ b/src/lib/form-field/_form-field-theme.scss @@ -124,9 +124,6 @@ $mat-form-field-dedupe: 0; // The amount to scale the font for the prefix and suffix icons. $prefix-suffix-icon-font-scale: 1.5; - // The amount of space between the top of the line and the top of the actual text - // (as a fraction of the font-size). - $line-spacing: ($line-height - 1) / 2; // The padding on the infix. Mocks show half of the text size. $infix-padding: 0.5em; // The margin applied to the form-field-infix to reserve space for the floating label. diff --git a/src/lib/form-field/form-field-box.scss b/src/lib/form-field/form-field-box.scss index a07886f3ed26..6701db092423 100644 --- a/src/lib/form-field/form-field-box.scss +++ b/src/lib/form-field/form-field-box.scss @@ -27,10 +27,6 @@ $mat-form-field-box-subscript-padding: $mat-form-field-box-side-padding; } - .mat-form-field-label { - transform: translateY(-50%); - } - .mat-form-field-underline { height: $mat-form-field-box-border-radius; border-radius: 0 0 $mat-form-field-box-border-radius $mat-form-field-box-border-radius; From d42ea81c27d21dde8d5898762a6dfd8b54f5e627 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Wed, 17 Jan 2018 14:45:59 -0800 Subject: [PATCH 13/19] remove bluriness fixes that aren't needed anymore --- src/lib/form-field/_form-field-box-theme.scss | 3 --- src/lib/form-field/_form-field-theme.scss | 3 --- src/lib/form-field/form-field-legacy.scss | 6 ------ src/lib/form-field/form-field.scss | 6 ------ 4 files changed, 18 deletions(-) diff --git a/src/lib/form-field/_form-field-box-theme.scss b/src/lib/form-field/_form-field-box-theme.scss index 757ae08676d9..104b73d56ff0 100644 --- a/src/lib/form-field/_form-field-box-theme.scss +++ b/src/lib/form-field/_form-field-box-theme.scss @@ -45,9 +45,6 @@ $mat-form-field-box-dedupe: 0; scale($font-scale); width: 100% / $font-scale + $mat-form-field-box-dedupe; - // Prevent text bluriness when label is floating. - backface-visibility: initial; - $mat-form-field-box-dedupe: $mat-form-field-box-dedupe + 0.00001 !global; } diff --git a/src/lib/form-field/_form-field-theme.scss b/src/lib/form-field/_form-field-theme.scss index 1514e008472f..ce385e0a31a0 100644 --- a/src/lib/form-field/_form-field-theme.scss +++ b/src/lib/form-field/_form-field-theme.scss @@ -109,9 +109,6 @@ $mat-form-field-dedupe: 0; scale($font-scale); width: 100% / $font-scale + $mat-form-field-dedupe; - // Prevent text bluriness when label is floating. - backface-visibility: initial; - $mat-form-field-dedupe: $mat-form-field-dedupe + 0.00001 !global; } diff --git a/src/lib/form-field/form-field-legacy.scss b/src/lib/form-field/form-field-legacy.scss index 4c1f3c8ad5b8..c2244c56fee2 100644 --- a/src/lib/form-field/form-field-legacy.scss +++ b/src/lib/form-field/form-field-legacy.scss @@ -9,13 +9,7 @@ $mat-form-field-legacy-underline-height: 1px !default; .mat-form-field-variant-legacy { - .mat-form-field-label-wrapper { - filter: initial; - } - .mat-form-field-label { - backface-visibility: initial; - transform: perspective(100px); -ms-transform: none; } diff --git a/src/lib/form-field/form-field.scss b/src/lib/form-field/form-field.scss index d664b4296765..51ac48d0a976 100644 --- a/src/lib/form-field/form-field.scss +++ b/src/lib/form-field/form-field.scss @@ -78,9 +78,6 @@ $mat-form-field-default-infix-width: 180px !default; height: 100%; overflow: hidden; pointer-events: none; // We shouldn't catch mouse events (let them through). - - // Helps prevent text jumpiness when transforming the label. - filter: blur(0); } // The label itself. This is invisible unless it is. The logic to show it is @@ -108,9 +105,6 @@ $mat-form-field-default-infix-width: 180px !default; // Hide the label initially, and only show it when it's floating or the control is empty. display: none; - // Helps prevent text jumpiness when transforming the label. - backface-visibility: hidden; - [dir='rtl'] & { transform-origin: 100% 0; left: auto; From a1deead7a53c360389efc810fd042021f852315f Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Wed, 17 Jan 2018 14:52:46 -0800 Subject: [PATCH 14/19] address comments --- src/lib/form-field/form-field.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/form-field/form-field.scss b/src/lib/form-field/form-field.scss index 51ac48d0a976..81472300087b 100644 --- a/src/lib/form-field/form-field.scss +++ b/src/lib/form-field/form-field.scss @@ -175,8 +175,8 @@ $mat-form-field-default-infix-width: 180px !default; opacity: 1; transform: scaleX(1); transition: transform 300ms $swift-ease-out-timing-function, - opacity 100ms $swift-ease-out-timing-function, - background-color 300ms $swift-ease-out-timing-function; + opacity 100ms $swift-ease-out-timing-function, + background-color 300ms $swift-ease-out-timing-function; } } From f81123f414abd28fd4acfe9807cbac10c6295fa3 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Wed, 17 Jan 2018 15:51:49 -0800 Subject: [PATCH 15/19] remove the floatLabel=never option in the new variants --- src/lib/form-field/form-field.ts | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/lib/form-field/form-field.ts b/src/lib/form-field/form-field.ts index f618f15ff182..b0e91c217f8b 100644 --- a/src/lib/form-field/form-field.ts +++ b/src/lib/form-field/form-field.ts @@ -122,11 +122,11 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte /** Whether the floating label should always float or not. */ get _shouldAlwaysFloat() { - return this._floatLabel === 'always' && !this._showAlwaysAnimate; + return this.floatLabel === 'always' && !this._showAlwaysAnimate; } /** Whether the label can float or not. */ - get _canLabelFloat() { return this._floatLabel !== 'never'; } + get _canLabelFloat() { return this.floatLabel !== 'never'; } /** State of the mat-hint and mat-error animations. */ _subscriptAnimationState: string = ''; @@ -148,12 +148,21 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte * @deprecated Use floatLabel instead. */ @Input() - get floatPlaceholder(): FloatLabelType { return this._floatLabel; } + get floatPlaceholder(): FloatLabelType { return this.floatLabel; } set floatPlaceholder(value: FloatLabelType) { this.floatLabel = value; } - /** Whether the label should always float, never float or float as the user types. */ + /** + * Whether the label should always float, never float or float as the user types. + * + * Note: only the legacy variant supports the `never` option. `never` was originally added as a + * way to make the floating label emulate the behavior of a standard input placeholder. However + * the form field now supports both floating labels and placeholders. Therefore in the non-legacy + * variants the `never` option has been disabled in favor of just using the placeholder. + */ @Input() - get floatLabel(): FloatLabelType { return this._floatLabel; } + get floatLabel(): FloatLabelType { + return this.variant !== 'legacy' && this._floatLabel === 'never' ? 'auto' : this._floatLabel; + } set floatLabel(value: FloatLabelType) { if (value !== this._floatLabel) { this._floatLabel = value || this._labelOptions.float || 'auto'; @@ -247,11 +256,14 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte } _hideControlPlaceholder() { - return !this._hasLabel() || !this._shouldLabelFloat(); + // In the legacy variant the placeholder is promoted to a label if no label is given. + return this.variant === 'legacy' && !this._hasLabel() || + this._hasLabel() && !this._shouldLabelFloat(); } _hasFloatingLabel() { - return this._hasLabel() || this._hasPlaceholder(); + // In the legacy variant the placeholder is promoted to a label if no label is given. + return this._hasLabel() || this.variant === 'legacy' && this._hasPlaceholder(); } /** Determines whether to display hints or errors. */ @@ -264,7 +276,7 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte _animateAndLockLabel(): void { if (this._hasFloatingLabel() && this._canLabelFloat) { this._showAlwaysAnimate = true; - this._floatLabel = 'always'; + this.floatLabel = 'always'; fromEvent(this._label.nativeElement, 'transitionend').pipe(take(1)).subscribe(() => { this._showAlwaysAnimate = false; From 72d74b879bc67aaa4ae55a65967d641dd5cdb71f Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 18 Jan 2018 09:07:41 -0800 Subject: [PATCH 16/19] variant --> appearance --- src/demo-app/input/input-demo.html | 26 +++++++++---------- src/demo-app/input/input-demo.ts | 6 ++--- src/lib/form-field/_form-field-box-theme.scss | 18 ++++++------- .../form-field/_form-field-legacy-theme.scss | 6 ++--- .../_form-field-standard-theme.scss | 4 +-- src/lib/form-field/_form-field-theme.scss | 2 +- src/lib/form-field/form-field-box.scss | 6 ++--- src/lib/form-field/form-field-legacy.scss | 4 +-- src/lib/form-field/form-field-standard.scss | 10 +++---- src/lib/form-field/form-field.scss | 2 +- src/lib/form-field/form-field.ts | 26 +++++++++---------- src/lib/select/select.scss | 4 +-- 12 files changed, 57 insertions(+), 57 deletions(-) diff --git a/src/demo-app/input/input-demo.html b/src/demo-app/input/input-demo.html index e7ea8f9c9935..b7554e92b19f 100644 --- a/src/demo-app/input/input-demo.html +++ b/src/demo-app/input/input-demo.html @@ -528,44 +528,44 @@

<textarea> with ngModel

- Variants + Appearance - - + + This field is required Please type something here - - + + This field is required Please type something here - - + + This field is required Please type something here
- - + + This field is required Please type something here - - + + This field is required Please type something here - - + + This field is required Please type something here diff --git a/src/demo-app/input/input-demo.ts b/src/demo-app/input/input-demo.ts index 4ea26d9cba27..04ed022cb3b6 100644 --- a/src/demo-app/input/input-demo.ts +++ b/src/demo-app/input/input-demo.ts @@ -52,9 +52,9 @@ export class InputDemo { delayedFormControl = new FormControl(''); model = 'hello'; - legacyVariant: string; - standardVariant: string; - boxVariant: string; + legacyAppearance: string; + standardAppearance: string; + boxAppearance: string; constructor() { setTimeout(() => this.delayedFormControl.setValue('hello'), 100); diff --git a/src/lib/form-field/_form-field-box-theme.scss b/src/lib/form-field/_form-field-box-theme.scss index 104b73d56ff0..7242c2307a0f 100644 --- a/src/lib/form-field/_form-field-box-theme.scss +++ b/src/lib/form-field/_form-field-box-theme.scss @@ -4,7 +4,7 @@ @import '../core/typography/typography-utils'; -// Theme styles that only apply to the box variant of the form-field. +// Theme styles that only apply to the box appearance of the form-field. @mixin mat-form-field-box-theme($theme) { $foreground: map-get($theme, foreground); @@ -14,7 +14,7 @@ $box-disabled-background: mat-color($foreground, base, if($is-dark-theme, 0.05, 0.03)); $underline-color: mat-color($foreground, divider, if($is-dark-theme, 0.7, 0.42)); - .mat-form-field-variant-box { + .mat-form-field-appearance-box { .mat-form-field-flex { background-color: $box-background; } @@ -57,26 +57,26 @@ $mat-form-field-box-dedupe: 0; $infix-padding: 0.5em; // The margin applied to the form-field-infix to reserve space for the floating label. $infix-margin-top: 1em * $line-height * $subscript-font-scale; - // The amount we offset the label in the box variant. - $box-variant-label-offset: -0.5em * $line-height; + // The amount we offset the label in the box appearance. + $box-appearance-label-offset: -0.5em * $line-height; - .mat-form-field-variant-box { + .mat-form-field-appearance-box { .mat-form-field-label { - margin-top: $box-variant-label-offset; + margin-top: $box-appearance-label-offset; } &.mat-form-field-can-float { &.mat-form-field-should-float .mat-form-field-label, .mat-input-server:focus + .mat-form-field-label-wrapper .mat-form-field-label { @include _mat-form-field-label-floating( - $subscript-font-scale, $infix-padding + $box-variant-label-offset, + $subscript-font-scale, $infix-padding + $box-appearance-label-offset, $infix-margin-top); } .mat-form-field-autofill-control:-webkit-autofill + .mat-form-field-label-wrapper .mat-form-field-label { @include _mat-form-field-label-floating( - $subscript-font-scale, $infix-padding + $box-variant-label-offset, + $subscript-font-scale, $infix-padding + $box-appearance-label-offset, $infix-margin-top); } @@ -85,7 +85,7 @@ $mat-form-field-box-dedupe: 0; .mat-input-server[label]:not(:label-shown) + .mat-form-field-label-wrapper .mat-form-field-label { @include _mat-form-field-label-floating( - $subscript-font-scale, $infix-padding + $box-variant-label-offset, + $subscript-font-scale, $infix-padding + $box-appearance-label-offset, $infix-margin-top); } } diff --git a/src/lib/form-field/_form-field-legacy-theme.scss b/src/lib/form-field/_form-field-legacy-theme.scss index e8fd48792816..6e09a89f1579 100644 --- a/src/lib/form-field/_form-field-legacy-theme.scss +++ b/src/lib/form-field/_form-field-legacy-theme.scss @@ -4,7 +4,7 @@ @import '../core/typography/typography-utils'; -// Theme styles that only apply to the legacy variant of the form-field. +// Theme styles that only apply to the legacy appearance of the form-field. @mixin mat-form-field-legacy-theme($theme) { $foreground: map-get($theme, foreground); @@ -12,7 +12,7 @@ $underline-color: mat-color($foreground, divider, if($is-dark-theme, 0.7, 0.42)); - .mat-form-field-variant-legacy { + .mat-form-field-appearance-legacy { .mat-form-field-underline { background-color: $underline-color; } @@ -71,7 +71,7 @@ $mat-form-field-legacy-dedupe: 0; // need to multiply by the subscript font scale factor since the wrapper has a larger font size. $wrapper-padding-bottom: ($subscript-margin-top + $line-height) * $subscript-font-scale; - .mat-form-field-variant-legacy { + .mat-form-field-appearance-legacy { .mat-form-field-wrapper { padding-bottom: $wrapper-padding-bottom; } diff --git a/src/lib/form-field/_form-field-standard-theme.scss b/src/lib/form-field/_form-field-standard-theme.scss index 6afd317be516..01d7e123c3e5 100644 --- a/src/lib/form-field/_form-field-standard-theme.scss +++ b/src/lib/form-field/_form-field-standard-theme.scss @@ -4,7 +4,7 @@ @import '../core/typography/typography-utils'; -// Theme styles that only apply to the standard variant of the form-field. +// Theme styles that only apply to the standard appearance of the form-field. @mixin mat-form-field-standard-theme($theme) { $foreground: map-get($theme, foreground); @@ -12,7 +12,7 @@ $underline-color: mat-color($foreground, divider, if($is-dark-theme, 0.7, 0.42)); - .mat-form-field-variant-standard { + .mat-form-field-appearance-standard { .mat-form-field-underline { background-color: $underline-color; } diff --git a/src/lib/form-field/_form-field-theme.scss b/src/lib/form-field/_form-field-theme.scss index ce385e0a31a0..2641e2c86363 100644 --- a/src/lib/form-field/_form-field-theme.scss +++ b/src/lib/form-field/_form-field-theme.scss @@ -7,7 +7,7 @@ @import 'form-field-standard-theme.scss'; -// Theme styles that apply to all variants of the form-field. +// Theme styles that apply to all appearances of the form-field. @mixin mat-form-field-theme($theme) { $primary: map-get($theme, primary); diff --git a/src/lib/form-field/form-field-box.scss b/src/lib/form-field/form-field-box.scss index 6701db092423..a939dd6bfba1 100644 --- a/src/lib/form-field/form-field-box.scss +++ b/src/lib/form-field/form-field-box.scss @@ -2,7 +2,7 @@ @import '../core/style/vendor-prefixes'; -// Styles that only apply to the box variant of the form-field. +// Styles that only apply to the box appearance of the form-field. // The border radius for the form field box. $mat-form-field-box-border-radius: 4px !default; @@ -14,13 +14,13 @@ $mat-form-field-box-side-padding: 1em !default; // between the floating label and the value. $mat-form-field-box-line-spacing: 0.5em !default; // The scale of the subscript and floating label text w.r.t the value text. -$mat-form-field-box-subscript-font-scale: .75 !default; +$mat-form-field-box-subscript-font-scale: 0.75 !default; // The horizontal padding between the edge of the subscript box and the start of the subscript text. $mat-form-field-box-subscript-padding: $mat-form-field-box-side-padding / $mat-form-field-box-subscript-font-scale; -.mat-form-field-variant-box { +.mat-form-field-appearance-box { .mat-form-field-flex { border-radius: $mat-form-field-box-border-radius; padding: $mat-form-field-box-line-spacing $mat-form-field-box-side-padding 0 diff --git a/src/lib/form-field/form-field-legacy.scss b/src/lib/form-field/form-field-legacy.scss index c2244c56fee2..301fea946862 100644 --- a/src/lib/form-field/form-field-legacy.scss +++ b/src/lib/form-field/form-field-legacy.scss @@ -2,13 +2,13 @@ @import '../core/style/vendor-prefixes'; -// Styles that only apply to the legacy variant of the form-field. +// Styles that only apply to the legacy appearance of the form-field. // The height of the underline. $mat-form-field-legacy-underline-height: 1px !default; -.mat-form-field-variant-legacy { +.mat-form-field-appearance-legacy { .mat-form-field-label { transform: perspective(100px); -ms-transform: none; diff --git a/src/lib/form-field/form-field-standard.scss b/src/lib/form-field/form-field-standard.scss index 920c911979cd..a79a00c00612 100644 --- a/src/lib/form-field/form-field-standard.scss +++ b/src/lib/form-field/form-field-standard.scss @@ -2,18 +2,18 @@ @import '../core/style/vendor-prefixes'; -// Styles that only apply to the standard variant of the form-field. +// Styles that only apply to the standard appearance of the form-field. // The height of the underline. $mat-form-field-standard-underline-height: 1px !default; -// The bottom margin of the underline (used to push it up to align with box variant underline). +// The bottom margin of the underline (used to push it up to align with box appearance underline). $mat-form-field-standard-underline-margin-bottom: 1px !default; // The padding between the top of the form field and the label text (used to align the standard -// form field with the box variant). -$mat-form-field-standard-padding-top: .5em !default; +// form field with the box appearance). +$mat-form-field-standard-padding-top: 0.5em !default; -.mat-form-field-variant-standard { +.mat-form-field-appearance-standard { .mat-form-field-flex { padding-top: $mat-form-field-standard-padding-top; } diff --git a/src/lib/form-field/form-field.scss b/src/lib/form-field/form-field.scss index 81472300087b..5e07a9513420 100644 --- a/src/lib/form-field/form-field.scss +++ b/src/lib/form-field/form-field.scss @@ -2,7 +2,7 @@ @import '../core/style/vendor-prefixes'; -// Styles that apply to all variants of the form-field. +// Styles that apply to all appearances of the form-field. // Min amount of space between start and end hint. $mat-form-field-hint-min-space: 1em !default; diff --git a/src/lib/form-field/form-field.ts b/src/lib/form-field/form-field.ts index b0e91c217f8b..7ded8522915e 100644 --- a/src/lib/form-field/form-field.ts +++ b/src/lib/form-field/form-field.ts @@ -46,7 +46,7 @@ import {MatSuffix} from './suffix'; let nextUniqueId = 0; -export type MatFormFieldVariant = 'legacy' | 'standard' | 'box'; +export type MatFormFieldAppearance = 'legacy' | 'standard' | 'box'; /** Container for form controls that applies Material Design styling and behavior. */ @@ -69,9 +69,9 @@ export type MatFormFieldVariant = 'legacy' | 'standard' | 'box'; animations: [matFormFieldAnimations.transitionMessages], host: { 'class': 'mat-input-container mat-form-field', - '[class.mat-form-field-variant-standard]': 'variant == "standard"', - '[class.mat-form-field-variant-box]': 'variant == "box"', - '[class.mat-form-field-variant-legacy]': 'variant == "legacy"', + '[class.mat-form-field-appearance-standard]': 'appearance == "standard"', + '[class.mat-form-field-appearance-box]': 'appearance == "box"', + '[class.mat-form-field-appearance-legacy]': 'appearance == "legacy"', '[class.mat-input-invalid]': '_control.errorState', '[class.mat-form-field-invalid]': '_control.errorState', '[class.mat-form-field-can-float]': '_canLabelFloat', @@ -98,8 +98,8 @@ export type MatFormFieldVariant = 'legacy' | 'standard' | 'box'; export class MatFormField implements AfterViewInit, AfterContentInit, AfterContentChecked { private _labelOptions: LabelOptions; - /** The form-field style variant. */ - @Input() variant: MatFormFieldVariant = 'legacy'; + /** The form-field appearance style. */ + @Input() appearance: MatFormFieldAppearance = 'legacy'; /** Color of the form field underline, based on the theme. */ @Input() color: 'primary' | 'accent' | 'warn' = 'primary'; @@ -154,14 +154,14 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte /** * Whether the label should always float, never float or float as the user types. * - * Note: only the legacy variant supports the `never` option. `never` was originally added as a + * Note: only the legacy appearance supports the `never` option. `never` was originally added as a * way to make the floating label emulate the behavior of a standard input placeholder. However * the form field now supports both floating labels and placeholders. Therefore in the non-legacy - * variants the `never` option has been disabled in favor of just using the placeholder. + * appearances the `never` option has been disabled in favor of just using the placeholder. */ @Input() get floatLabel(): FloatLabelType { - return this.variant !== 'legacy' && this._floatLabel === 'never' ? 'auto' : this._floatLabel; + return this.appearance !== 'legacy' && this._floatLabel === 'never' ? 'auto' : this._floatLabel; } set floatLabel(value: FloatLabelType) { if (value !== this._floatLabel) { @@ -256,14 +256,14 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte } _hideControlPlaceholder() { - // In the legacy variant the placeholder is promoted to a label if no label is given. - return this.variant === 'legacy' && !this._hasLabel() || + // In the legacy appearance the placeholder is promoted to a label if no label is given. + return this.appearance === 'legacy' && !this._hasLabel() || this._hasLabel() && !this._shouldLabelFloat(); } _hasFloatingLabel() { - // In the legacy variant the placeholder is promoted to a label if no label is given. - return this._hasLabel() || this.variant === 'legacy' && this._hasPlaceholder(); + // In the legacy appearance the placeholder is promoted to a label if no label is given. + return this._hasLabel() || this.appearance === 'legacy' && this._hasPlaceholder(); } /** Determines whether to display hints or errors. */ diff --git a/src/lib/select/select.scss b/src/lib/select/select.scss index 12a6d82324e6..1a8305512d7b 100644 --- a/src/lib/select/select.scss +++ b/src/lib/select/select.scss @@ -46,8 +46,8 @@ $mat-select-placeholder-arrow-space: 2 * ($mat-select-arrow-size + $mat-select-a display: table-cell; vertical-align: middle; - // When used in a box variant form-field the arrow should be centered in the box. - .mat-form-field-variant-box & { + // When used in a box appearance form-field the arrow should be centered in the box. + .mat-form-field-appearance-box & { transform: translateY(-50%); } } From b29ea3477ceb21599a2ad9c64c1d0f9606e090b6 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 18 Jan 2018 09:30:10 -0800 Subject: [PATCH 17/19] add tests for new label & placeholder behavior --- src/lib/input/input.spec.ts | 84 ++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/src/lib/input/input.spec.ts b/src/lib/input/input.spec.ts index a74de097c758..d3242a582de7 100644 --- a/src/lib/input/input.spec.ts +++ b/src/lib/input/input.spec.ts @@ -21,7 +21,7 @@ import { getMatFormFieldDuplicatedHintError, getMatFormFieldMissingControlError, getMatFormFieldPlaceholderConflictError, - MatFormField, + MatFormField, MatFormFieldAppearance, MatFormFieldModule, } from '@angular/material/form-field'; import {By} from '@angular/platform-browser'; @@ -1132,6 +1132,76 @@ describe('MatInput with forms', () => { })); }); +describe('MatInput with appearance', () => { + const nonLegacyAppearances: MatFormFieldAppearance[] = ['standard', 'box']; + let fixture: ComponentFixture; + let testComponent: MatInputWithAppearance; + let containerEl: HTMLElement; + + beforeEach(fakeAsync(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + MatFormFieldModule, + MatInputModule, + NoopAnimationsModule, + PlatformModule, + ReactiveFormsModule, + ], + declarations: [ + MatInputWithAppearance, + ], + }); + + TestBed.compileComponents(); + })); + + beforeEach(fakeAsync(() => { + fixture = TestBed.createComponent(MatInputWithAppearance); + fixture.detectChanges(); + testComponent = fixture.componentInstance; + containerEl = fixture.debugElement.query(By.css('mat-form-field')).nativeElement; + })); + + it('legacy appearance should promote placeholder to label', fakeAsync(() => { + testComponent.appearance = 'legacy'; + fixture.detectChanges(); + + expect(containerEl.classList).toContain('mat-form-field-appearance-legacy'); + expect(testComponent.formField._hasFloatingLabel()).toBe(true); + expect(testComponent.formField._hideControlPlaceholder()).toBe(true); + })); + + it('non-legacy appearances should not promote placeholder to label', fakeAsync(() => { + for (let appearance of nonLegacyAppearances) { + testComponent.appearance = appearance; + fixture.detectChanges(); + + expect(containerEl.classList).toContain(`mat-form-field-appearance-${appearance}`); + expect(testComponent.formField._hasFloatingLabel()).toBe(false); + expect(testComponent.formField._hideControlPlaceholder()).toBe(false); + } + })); + + it('legacy appearance should respect float never', fakeAsync(() => { + testComponent.appearance = 'legacy'; + fixture.detectChanges(); + + expect(containerEl.classList).toContain('mat-form-field-appearance-legacy'); + expect(testComponent.formField.floatLabel).toBe('never'); + })); + + it('non-legacy appearances should not respect float never', fakeAsync(() => { + for (let appearance of nonLegacyAppearances) { + testComponent.appearance = appearance; + fixture.detectChanges(); + + expect(containerEl.classList).toContain(`mat-form-field-appearance-${appearance}`); + expect(testComponent.formField.floatLabel).toBe('auto'); + } + })); +}); + @Component({ template: ` @@ -1467,3 +1537,15 @@ class MatInputWithReadonlyInput {} class MatInputWithLabelAndPlaceholder { floatLabel: FloatLabelType; } + +@Component({ + template: ` + + + + ` +}) +class MatInputWithAppearance { + @ViewChild(MatFormField) formField: MatFormField; + appearance: MatFormFieldAppearance; +} From b86428543d41cede46bc108e3ee32fd16ab87a31 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 18 Jan 2018 11:43:53 -0800 Subject: [PATCH 18/19] update demo to use mat-label --- .../a11y/autocomplete/autocomplete-a11y.html | 3 +- .../a11y/datepicker/datepicker-a11y.html | 16 +- .../a11y/dialog/dialog-address-form-a11y.html | 24 ++- src/demo-app/a11y/input/input-a11y.html | 20 ++- src/demo-app/a11y/select/select-a11y.html | 27 ++- .../autocomplete/autocomplete-demo.html | 8 +- src/demo-app/baseline/baseline-demo.html | 18 +- src/demo-app/datepicker/datepicker-demo.html | 27 +-- src/demo-app/dialog/dialog-demo.html | 42 +++-- src/demo-app/dialog/dialog-demo.ts | 3 +- src/demo-app/expansion/expansion-demo.html | 6 +- src/demo-app/input/input-demo.html | 157 +++++++++++------- src/demo-app/ripple/ripple-demo.html | 6 +- src/demo-app/select/select-demo.html | 28 ++-- src/demo-app/snack-bar/snack-bar-demo.html | 4 +- src/demo-app/stepper/stepper-demo.html | 48 ++++-- src/demo-app/table/table-demo.html | 3 +- src/demo-app/tabs/tabs-demo.html | 15 +- 18 files changed, 289 insertions(+), 166 deletions(-) diff --git a/src/demo-app/a11y/autocomplete/autocomplete-a11y.html b/src/demo-app/a11y/autocomplete/autocomplete-a11y.html index e84762443315..95c5df20d85e 100644 --- a/src/demo-app/a11y/autocomplete/autocomplete-a11y.html +++ b/src/demo-app/a11y/autocomplete/autocomplete-a11y.html @@ -2,7 +2,8 @@

Filtering and selection

Select your favorite state

- Search for a state + diff --git a/src/demo-app/a11y/datepicker/datepicker-a11y.html b/src/demo-app/a11y/datepicker/datepicker-a11y.html index 9b1301e668ac..48692bf20fbd 100644 --- a/src/demo-app/a11y/datepicker/datepicker-a11y.html +++ b/src/demo-app/a11y/datepicker/datepicker-a11y.html @@ -1,13 +1,13 @@

Choose a date (e.g. choose your date of birth)

+ Date of birth + required> @@ -44,14 +44,14 @@

Choose a date with touch UI (e.g. choose a payment date on mobile)

Choose date with startAt, min and max (e.g. schedule a departing and returning flight)

+ Departure date + required> @@ -65,13 +65,13 @@

Choose date with startAt, min and max (e.g. schedule a departing and returni + Return date + [max]="maxTripDate"> @@ -89,6 +89,7 @@

Choose date with startAt, min and max (e.g. schedule a departing and returni

Choose date with date filter (e.g. schedule a doctor's appointment)

+ Appointment date Choose date with date filter (e.g. schedule a doctor's appointment)

[min]="minAppointmentDate" [max]="maxAppointmentDate" [matDatepickerFilter]="weekdaysOnly" - required - placeholder="Appointment date"> + required> diff --git a/src/demo-app/a11y/dialog/dialog-address-form-a11y.html b/src/demo-app/a11y/dialog/dialog-address-form-a11y.html index abbeb3440645..7c0644ef6b0c 100644 --- a/src/demo-app/a11y/dialog/dialog-address-form-a11y.html +++ b/src/demo-app/a11y/dialog/dialog-address-form-a11y.html @@ -3,36 +3,44 @@

Company

- + Company (disabled) +
- + First name + - + Long last name that will be truncated +

- + Address + - + Address 2 +

- + City + - + State + - + Postal code + {{postalCode.value.length}} / 5
diff --git a/src/demo-app/a11y/input/input-a11y.html b/src/demo-app/a11y/input/input-a11y.html index cb9d19dfb345..006b85707ac3 100644 --- a/src/demo-app/a11y/input/input-a11y.html +++ b/src/demo-app/a11y/input/input-a11y.html @@ -1,18 +1,20 @@

Basic input box (e.g. name field)

- + First name + - + Last name +

Input with hint (e.g. password field)

- + Password +

[max]="maxDate" [matDatepickerFilter]="filterOdd ? dateFilter : null" [disabled]="inputDisabled" - placeholder="Pick a date" (dateInput)="onDateInput($event)" (dateChange)="onDateChange($event)"> Input disabled datepicker

+ Input disabled + [matDatepickerFilter]="filterOdd ? dateFilter : null" disabled> @@ -98,9 +101,9 @@

Input disabled via FormControl

+ FormControl disabled + [max]="maxDate" [matDatepickerFilter]="filterOdd ? dateFilter : null"> @@ -114,9 +117,9 @@

Input disabled, datepicker popup enabled

+ Input disabled, datepicker enabled + [max]="maxDate" [matDatepickerFilter]="filterOdd ? dateFilter : null"> @@ -126,9 +129,9 @@

Datepicker with value property binding

+ Value binding + [max]="maxDate" [matDatepickerFilter]="filterOdd ? dateFilter : null"> diff --git a/src/demo-app/dialog/dialog-demo.html b/src/demo-app/dialog/dialog-demo.html index dcb68eb03872..a4e2fba1eecb 100644 --- a/src/demo-app/dialog/dialog-demo.html +++ b/src/demo-app/dialog/dialog-demo.html @@ -16,28 +16,34 @@

Dialog dimensions

- + Width + - + Height +

- + Min width + - + Min height +

- + Max width + - + Max height +

@@ -45,19 +51,23 @@

Dialog position

- + Top + - + Bottom +

- + Left + - + Right +

@@ -65,7 +75,8 @@

Dialog backdrop

- + Backdrop class +

@@ -75,7 +86,8 @@

Other options

- + Button alignment + Start End Center @@ -85,7 +97,8 @@

Other options

- + Dialog message +

@@ -104,7 +117,8 @@

Other options

It's Jazz!

- + How much? +

{{ data.message }}

diff --git a/src/demo-app/dialog/dialog-demo.ts b/src/demo-app/dialog/dialog-demo.ts index 8e4ba9e3bd7a..b519069b7dc3 100644 --- a/src/demo-app/dialog/dialog-demo.ts +++ b/src/demo-app/dialog/dialog-demo.ts @@ -92,7 +92,8 @@ export class DialogDemo {

It's Jazz!

- + How much? +

{{ data.message }}

diff --git a/src/demo-app/expansion/expansion-demo.html b/src/demo-app/expansion/expansion-demo.html index 9e4ecb03f322..d3b0a94b375f 100644 --- a/src/demo-app/expansion/expansion-demo.html +++ b/src/demo-app/expansion/expansion-demo.html @@ -19,11 +19,13 @@

Single Expansion Panel


- + Collapsed height + - + Expanded height +
diff --git a/src/demo-app/input/input-demo.html b/src/demo-app/input/input-demo.html index b7554e92b19f..c9932a43e58a 100644 --- a/src/demo-app/input/input-demo.html +++ b/src/demo-app/input/input-demo.html @@ -3,44 +3,51 @@ - + Company (disabled) +
- + First name + - + Long last name that will be truncated +

- + Address + - + Address 2 +

@@ -377,10 +410,13 @@

Textarea

Forms - + + Reactive + - + Template +
- + Delayed value +
@@ -509,10 +546,10 @@

Regular <textarea>

<textarea> with mat-form-field

+ Autosized textarea + matAutosizeMaxRows="10">
@@ -531,19 +568,22 @@

<textarea> with ngModel

Appearance - + Legacy appearance + This field is required Please type something here - + Standard appearance + This field is required Please type something here - + Box appearance + This field is required Please type something here @@ -551,21 +591,24 @@

<textarea> with ngModel

- + City + - + State + - + Postal code + mode_edit {{postalCode.value.length}} / 5 @@ -59,12 +66,14 @@

Regular

- + Example + This field is required - + Email + This field is required @@ -77,7 +86,8 @@

Regular

With hint

- + Example + This field is required Please type something here @@ -87,8 +97,8 @@

With hint

Inside a form

- + Example + This field is required @@ -97,8 +107,8 @@

Inside a form

With a custom error function

+ Example @@ -113,21 +123,24 @@

With a custom error function

Text

- + Amount + .00

Icons

- + Amount + attach_money mode_edit

Icon buttons

- + Amount + @@ -139,37 +152,46 @@

Icon buttons

Input

- + Default color + - + Accent color + - + Warn color +

Textarea

- + Default color + - + Accent color + - + Warn color +

With error

- + Default color + This field is required - + Accent color + This field is required - + Warn color + This field is required
@@ -181,9 +203,9 @@

With error

Input

+ Character count (100 max) @@ -195,9 +217,9 @@

Input

Textarea

+ Character count (100 max) {{characterCountTextareaHintExample.value.length}} / 100 @@ -212,7 +234,8 @@

Textarea

Hello  - + First name + , how are you? @@ -220,35 +243,40 @@

Textarea

- + Disabled field + - + Required field +

- + 100% width label +

- + Character count (100 max) + {{input.value.length}} / 100

- + Show hint label +

- - I favorite bold placeholder - + + I favorite bold label + I also home italic hint labels @@ -256,13 +284,15 @@

Textarea

- + Show hint label with character count + {{hintLabelWithCharCount.value.length}}

- + Enter text to count + Enter some text to count how many characters are in it. The character count is shown on the right. @@ -305,7 +335,8 @@

Textarea

- + Label +

@@ -318,17 +349,20 @@

Textarea

- + Prefixed +

Example: 
- + Suffixed + .00 €
Both: - + Email address + email   @gmail.com @@ -358,10 +392,9 @@

Textarea

{{i+1}} + Value
- + Legacy appearance + This field is required Please type something here - + Standard appearance + This field is required Please type something here - + Box appearance + This field is required Please type something here diff --git a/src/demo-app/ripple/ripple-demo.html b/src/demo-app/ripple/ripple-demo.html index 98feef4e9d23..9b0b8180cc3e 100644 --- a/src/demo-app/ripple/ripple-demo.html +++ b/src/demo-app/ripple/ripple-demo.html @@ -28,10 +28,12 @@
- + Ripple radius + - + Ripple color +
diff --git a/src/demo-app/select/select-demo.html b/src/demo-app/select/select-demo.html index dd1ca63c25a5..0d199f581348 100644 --- a/src/demo-app/select/select-demo.html +++ b/src/demo-app/select/select-demo.html @@ -7,7 +7,8 @@ ngModel - Drink + None @@ -50,7 +51,8 @@ - Pokemon + {{ creature.viewValue }} @@ -78,7 +80,8 @@ Without Angular forms - + Digimon + None {{ creature.viewValue }} @@ -97,7 +100,8 @@ - + Pokemon + @@ -114,11 +118,11 @@ compareWith - + Drink + {{ drink.viewValue }} @@ -146,7 +150,8 @@ - + Food I would like to eat + {{ food.viewValue }} @@ -167,7 +172,8 @@ - + Starter pokemon + {{ creature.viewValue }} diff --git a/src/demo-app/snack-bar/snack-bar-demo.html b/src/demo-app/snack-bar/snack-bar-demo.html index 1bdb4819e7aa..9593e6034324 100644 --- a/src/demo-app/snack-bar/snack-bar-demo.html +++ b/src/demo-app/snack-bar/snack-bar-demo.html @@ -25,10 +25,10 @@

SnackBar demo

Show button on snack bar

+ Snack bar action label
@@ -37,10 +37,10 @@

SnackBar demo

Auto hide after duration

+ Auto hide duration in ms
diff --git a/src/demo-app/stepper/stepper-demo.html b/src/demo-app/stepper/stepper-demo.html index 0dd4274921ba..40f2828e2a0b 100644 --- a/src/demo-app/stepper/stepper-demo.html +++ b/src/demo-app/stepper/stepper-demo.html @@ -6,12 +6,14 @@

Linear Vertical Stepper Demo using a single form

Fill out your name - + First name + This field is required - + Last name + This field is required
@@ -24,7 +26,8 @@

Linear Vertical Stepper Demo using a single form

Fill out your email address
- + Email address + The input is invalid.
@@ -49,11 +52,13 @@

Linear Horizontal Stepper Demo using a different form for each step

Fill out your name - + First name + This field is required - + Last name + This field is required
@@ -66,7 +71,8 @@

Linear Horizontal Stepper Demo using a different form for each step

Fill out your email address - + Email address + The input is invalid
@@ -93,11 +99,13 @@

Vertical Stepper Demo

Fill out your name - + First name + - + Last name +
@@ -109,7 +117,8 @@

Vertical Stepper Demo

Fill out your phone number
- + Phone number +
@@ -122,7 +131,8 @@

Vertical Stepper Demo

Fill out your address
- + Address +
@@ -143,11 +153,13 @@

Horizontal Stepper Demo with Text Label

- + First name + - + Last name +
@@ -156,7 +168,8 @@

Horizontal Stepper Demo with Text Label

- + Phone number +
@@ -166,7 +179,8 @@

Horizontal Stepper Demo with Text Label

- + Address +
@@ -187,7 +201,8 @@

Horizontal Stepper Demo with Templated Label

{{step.label}} - + Answer +
@@ -200,7 +215,8 @@

Stepper with autosize textarea

- + Autosize textarea + diff --git a/src/demo-app/table/table-demo.html b/src/demo-app/table/table-demo.html index f25906d05ca4..5fdf813f6bf9 100644 --- a/src/demo-app/table/table-demo.html +++ b/src/demo-app/table/table-demo.html @@ -214,7 +214,8 @@

MatTable Using 'When' Rows for Interactive Details

MatTable With MatTableDataSource Example

- + Filter users +
diff --git a/src/demo-app/tabs/tabs-demo.html b/src/demo-app/tabs/tabs-demo.html index 8b85ef763f3d..8c1ac8261ad0 100644 --- a/src/demo-app/tabs/tabs-demo.html +++ b/src/demo-app/tabs/tabs-demo.html @@ -89,7 +89,8 @@

Tab Group Demo - Dynamic Tabs



- + Tab label +

@@ -187,7 +189,8 @@

Tab Group Demo - Fixed Height



- + Tab label +
@@ -217,7 +220,8 @@

Async Tabs



- + Tab label +
@@ -283,7 +287,8 @@

Tabs with autosize textarea

- + Autosize textarea +
From 43b00d83bdcf6c10a902aaa8689b5192a020b061 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 18 Jan 2018 13:46:00 -0800 Subject: [PATCH 19/19] fix bazel build --- src/lib/form-field/BUILD.bazel | 44 ++++++++++++++++++++++++++++++++-- src/lib/input/input.spec.ts | 9 +++---- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/lib/form-field/BUILD.bazel b/src/lib/form-field/BUILD.bazel index f88d4b2e648d..77b35dda754e 100644 --- a/src/lib/form-field/BUILD.bazel +++ b/src/lib/form-field/BUILD.bazel @@ -9,6 +9,9 @@ ng_module( module_name = "@angular/material/form-field", assets = [ ":form_field_css", + ":form_field_box_css", + ":form_field_legacy_css", + ":form_field_standard_css", "//src/lib/input:input_css" ], deps = [ @@ -19,14 +22,31 @@ ng_module( tsconfig = ":tsconfig-build.json", ) - sass_binary( name = "form_field_scss", src = "form-field.scss", deps = ["//src/lib/core:core_scss_lib"], ) -# TODO(jelbourn): remove this when sass_binary supports specifying an output filename and dir. +sass_binary( + name = "form_field_box_scss", + src = "form-field-box.scss", + deps = ["//src/lib/core:core_scss_lib"], +) + +sass_binary( + name = "form_field_legacy_scss", + src = "form-field-legacy.scss", + deps = ["//src/lib/core:core_scss_lib"], +) + +sass_binary( + name = "form_field_standard_scss", + src = "form-field-standard.scss", + deps = ["//src/lib/core:core_scss_lib"], +) + +# TODO(jelbourn): remove these when sass_binary supports specifying an output filename and dir. # Copy the output of the sass_binary such that the filename and path match what we expect. genrule( name = "form_field_css", @@ -35,3 +55,23 @@ genrule( cmd = "cat $(locations :form_field_scss) > $@", ) +genrule( + name = "form_field_box_css", + srcs = [":form_field_box_scss"], + outs = ["form-field-box.css"], + cmd = "cat $(locations :form_field_box_scss) > $@", +) + +genrule( + name = "form_field_legacy_css", + srcs = [":form_field_legacy_scss"], + outs = ["form-field-legacy.css"], + cmd = "cat $(locations :form_field_legacy_scss) > $@", +) + +genrule( + name = "form_field_standard_css", + srcs = [":form_field_standard_scss"], + outs = ["form-field-standard.css"], + cmd = "cat $(locations :form_field_standard_scss) > $@", +) diff --git a/src/lib/input/input.spec.ts b/src/lib/input/input.spec.ts index d3242a582de7..a8893544a7c0 100644 --- a/src/lib/input/input.spec.ts +++ b/src/lib/input/input.spec.ts @@ -1,7 +1,7 @@ import {Platform, PlatformModule} from '@angular/cdk/platform'; import {createFakeEvent, dispatchFakeEvent, wrappedErrorMessage} from '@angular/cdk/testing'; import {ChangeDetectionStrategy, Component, ViewChild} from '@angular/core'; -import {ComponentFixture, inject, TestBed, fakeAsync, flush} from '@angular/core/testing'; +import {ComponentFixture, fakeAsync, flush, inject, TestBed} from '@angular/core/testing'; import { FormControl, FormGroup, @@ -12,16 +12,17 @@ import { Validators, } from '@angular/forms'; import { - MAT_LABEL_GLOBAL_OPTIONS, - ShowOnDirtyErrorStateMatcher, ErrorStateMatcher, FloatLabelType, + MAT_LABEL_GLOBAL_OPTIONS, + ShowOnDirtyErrorStateMatcher, } from '@angular/material/core'; import { getMatFormFieldDuplicatedHintError, getMatFormFieldMissingControlError, getMatFormFieldPlaceholderConflictError, - MatFormField, MatFormFieldAppearance, + MatFormField, + MatFormFieldAppearance, MatFormFieldModule, } from '@angular/material/form-field'; import {By} from '@angular/platform-browser';