diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 021ad34aef1a..34fcc471d7ec 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -41,6 +41,7 @@
/src/lib/core/line/** @jelbourn
/src/lib/core/option/** @kara @crisbeto
/src/lib/core/placeholder/** @kara @mmalerba
+/src/lib/core/label/** @kara @mmalerba
/src/lib/core/ripple/** @devversion
/src/lib/core/selection/** @tinayuangao @jelbourn
/src/lib/core/selection/pseudo*/** @crisbeto @jelbourn
diff --git a/guides/creating-a-custom-form-field-control.md b/guides/creating-a-custom-form-field-control.md
index 479670ec5082..738b24b25d73 100644
--- a/guides/creating-a-custom-form-field-control.md
+++ b/guides/creating-a-custom-form-field-control.md
@@ -211,16 +211,16 @@ get empty() {
}
```
-#### `shouldPlaceholderFloat`
+#### `shouldLabelFloat`
-This property is used to indicate whether the placeholder should be in the floating position. We'll
+This property is used to indicate whether the label should be in the floating position. We'll
use the same logic as `matInput` and float the placeholder when the input is focused or non-empty.
Since the placeholder will be overlapping our control when when it's not floating, we should hide
the `–` characters when it's not floating.
```ts
@HostBinding('class.floating')
-get shouldPlaceholderFloat() {
+get shouldLabelFloat() {
return this.focused || !this.empty;
}
```
diff --git a/src/demo-app/a11y/input/input-a11y.html b/src/demo-app/a11y/input/input-a11y.html
index 8129ee38d788..cb9d19dfb345 100644
--- a/src/demo-app/a11y/input/input-a11y.html
+++ b/src/demo-app/a11y/input/input-a11y.html
@@ -1,9 +1,9 @@
Basic input box (e.g. name field)
-
+
-
+
@@ -34,12 +34,12 @@
Input with error message (e.g. email field)
Input with prefix & suffix (e.g. currency converter)
diff --git a/src/lib/form-field/form-field.md b/src/lib/form-field/form-field.md
index 19d954a98e26..c28164137e08 100644
--- a/src/lib/form-field/form-field.md
+++ b/src/lib/form-field/form-field.md
@@ -13,35 +13,39 @@ The following Angular Material components are designed to work inside a `
-### Floating placeholder
+### Floating label
-The floating placeholder is a text label displayed on top of the form field control when
-the control does not contain any text. By default, when text is present the floating placeholder
-floats above the form field control.
+The floating label is a text label displayed on top of the form field control when
+the control does not contain any text. By default, when text is present the floating label
+floats above the form field control. The label for a form field can be defined either through a
+`mat-label` element, by setting the `placeholder` attribute on the form control or using the
+`mat-placeholder` element. If there are multiple clashing values (e.g. a `placeholder` and a
+label) the `mat-label` will take precedence and the `placeholder` will be shown only when there is
+no value.
Placeholder text can be specified using the `placeholder` property on the form field control, or
by adding a `` element inside the form field. Only one of these options should be
used, specifying both will raise an error.
If the form field control is marked with a `required` attribute, an asterisk will be appended to the
-placeholder to indicate the fact that it is a required field. If unwanted, this can be disabled by
+label to indicate the fact that it is a required field. If unwanted, this can be disabled by
setting the `hideRequiredMarker` property on ``
-The `floatPlaceholder` property of `` can be used to change this default floating
-behavior. It can set to `never` to hide the placeholder instead of float it when text is present in
-the form field control. It can be set to `always` to float the placeholder even when no text is
+The `floatLabel` property of `` can be used to change this default floating
+behavior. It can set to `never` to hide the label instead of float it when text is present in
+the form field control. It can be set to `always` to float the label even when no text is
present in the form field control. It can also be set to `auto` to restore the default behavior.
-
+
-Global default placeholder options can be specified by setting providing a value for
-`MAT_PLACEHOLDER_GLOBAL_OPTIONS` in your application's root module. Like the property, the global
+Global default label options can be specified by setting providing a value for
+`MAT_LABEL_GLOBAL_OPTIONS` in your application's root module. Like the property, the global
setting can be either `always`, `never`, or `auto`.
```ts
@NgModule({
providers: [
- {provide: MAT_PLACEHOLDER_GLOBAL_OPTIONS, useValue: {float: 'always'}}
+ {provide: MAT_LABEL_GLOBAL_OPTIONS, useValue: {float: 'always'}}
]
})
```
@@ -96,7 +100,7 @@ information on this see the guide on
### Theming
`` has a `color` property which can be set to `primary`, `accent`, or `warn`. This
-will set the color of the form field underline and floating placeholder based on the theme colors
+will set the color of the form field underline and floating label based on the theme colors
of your app.
`` inherits its `font-size` from its parent element. This can be overridden to an
@@ -112,8 +116,8 @@ mat-form-field.mat-form-field {
### Accessibility
-If a floating placeholder is specified, it will be automatically used as the label for the form
-field control. If no floating placeholder is specified, the user should label the form field control
+If a floating label is specified, it will be automatically used as the label for the form
+field control. If no floating label is specified, the user should label the form field control
themselves using `aria-label`, `aria-labelledby` or ``.
Any errors and hints added to the form field are automatically added to the form field control's
diff --git a/src/lib/form-field/form-field.scss b/src/lib/form-field/form-field.scss
index 693ec33ea5c3..c0a51303fe03 100644
--- a/src/lib/form-field/form-field.scss
+++ b/src/lib/form-field/form-field.scss
@@ -67,9 +67,9 @@ $mat-form-field-default-infix-width: 180px !default;
width: $mat-form-field-default-infix-width;
}
-// Used to hide the placeholder overflow on IE, since IE doesn't take transform into account when
+// Used to hide the label overflow on IE, since IE doesn't take transform into account when
// determining overflow.
-.mat-form-field-placeholder-wrapper {
+.mat-form-field-label-wrapper {
position: absolute;
left: 0;
box-sizing: content-box;
@@ -79,12 +79,11 @@ $mat-form-field-default-infix-width: 180px !default;
pointer-events: none; // We shouldn't catch mouse events (let them through).
}
-// The placeholder label. This is invisible unless it is. The logic to show it is
+// The label itself. This is invisible unless it is. The logic to show it is
// basically `empty || (float && (!empty || focused))`. Float is dependent on the
// `floatingPlaceholder` property.
-.mat-form-field-placeholder {
- // The placeholder is after the form field control, but needs to be aligned top-left of the
- // infix
.
+.mat-form-field-label {
+ // The label is after the form field control, but needs to be aligned top-left of the infix
.
position: absolute;
left: 0;
@@ -106,7 +105,7 @@ $mat-form-field-default-infix-width: 180px !default;
color $swift-ease-out-duration $swift-ease-out-timing-function,
width $swift-ease-out-duration $swift-ease-out-timing-function;
- // Hide the placeholder initially, and only show it when it's floating or the control is empty.
+ // Hide the label initially, and only show it when it's floating or the control is empty.
display: none;
[dir='rtl'] & {
@@ -116,18 +115,18 @@ $mat-form-field-default-infix-width: 180px !default;
}
}
-.mat-form-field-empty.mat-form-field-placeholder,
-.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-placeholder {
+.mat-form-field-empty.mat-form-field-label,
+.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label {
display: block;
}
-// Pseudo-class for Chrome and Safari auto-fill to move the placeholder to the floating position.
+// Pseudo-class for Chrome and Safari auto-fill to move the label to the floating position.
// This is necessary because these browsers do not actually fire any events when a form auto-fill is
// occurring. Once the autofill is committed, a change event happen and the regular mat-form-field
// classes take over to fulfill this behaviour.
-.mat-form-field-autofill-control:-webkit-autofill + .mat-form-field-placeholder-wrapper
- .mat-form-field-placeholder {
- // The form field will be considered empty if it is autofilled, and therefore the placeholder will
+.mat-form-field-autofill-control:-webkit-autofill + .mat-form-field-label-wrapper
+ .mat-form-field-label {
+ // The form field will be considered empty if it is autofilled, and therefore the label will
// be shown. Therefore we need to override it to hidden...
display: none;
@@ -150,9 +149,9 @@ $mat-form-field-default-infix-width: 180px !default;
}
}
-// Disable the placeholder animation when the control is not empty (this prevents placeholder
+// Disable the label animation when the control is not empty (this prevents label
// animating up when the value is set programmatically).
-.mat-form-field-placeholder:not(.mat-form-field-empty) {
+.mat-form-field-label:not(.mat-form-field-empty) {
transition: none;
}
@@ -200,9 +199,9 @@ $mat-form-field-default-infix-width: 180px !default;
overflow: hidden; // prevents multi-line errors from overlapping the control
}
-// Scale down icons in the placeholder and hint to be the same size as the text.
+// Scale down icons in the label and hint to be the same size as the text.
.mat-form-field-subscript-wrapper,
-.mat-form-field-placeholder-wrapper {
+.mat-form-field-label-wrapper {
.mat-icon {
width: 1em;
height: 1em;
diff --git a/src/lib/form-field/form-field.ts b/src/lib/form-field/form-field.ts
index c1046cfa3e52..6117e930cc23 100644
--- a/src/lib/form-field/form-field.ts
+++ b/src/lib/form-field/form-field.ts
@@ -27,11 +27,7 @@ import {
ViewChild,
ViewEncapsulation,
} from '@angular/core';
-import {
- FloatPlaceholderType,
- MAT_PLACEHOLDER_GLOBAL_OPTIONS,
- PlaceholderOptions,
-} from '@angular/material/core';
+import {FloatLabelType, MAT_LABEL_GLOBAL_OPTIONS, LabelOptions} from '@angular/material/core';
import {fromEvent} from 'rxjs/observable/fromEvent';
import {MatError} from './error';
import {MatFormFieldControl} from './form-field-control';
@@ -42,6 +38,7 @@ import {
} from './form-field-errors';
import {MatHint} from './hint';
import {MatPlaceholder} from './placeholder';
+import {MatLabel} from './label';
import {MatPrefix} from './prefix';
import {MatSuffix} from './suffix';
@@ -61,7 +58,7 @@ let nextUniqueId = 0;
// aren't using MatInput.
styleUrls: ['form-field.css', '../input/input.css'],
animations: [
- // TODO(mmalerba): Use angular animations for placeholder animation as well.
+ // TODO(mmalerba): Use angular animations for label animation as well.
trigger('transitionMessages', [
state('enter', style({ opacity: 1, transform: 'translateY(0%)' })),
transition('void => enter', [
@@ -74,8 +71,9 @@ let nextUniqueId = 0;
'class': 'mat-input-container mat-form-field',
'[class.mat-input-invalid]': '_control.errorState',
'[class.mat-form-field-invalid]': '_control.errorState',
- '[class.mat-form-field-can-float]': '_canPlaceholderFloat',
- '[class.mat-form-field-should-float]': '_control.shouldPlaceholderFloat || _shouldAlwaysFloat',
+ '[class.mat-form-field-can-float]': '_canLabelFloat',
+ '[class.mat-form-field-should-float]': '_shouldLabelFloat()',
+ '[class.mat-form-field-hide-placeholder]': '_hideControlPlaceholder()',
'[class.mat-form-field-disabled]': '_control.disabled',
'[class.mat-focused]': '_control.focused',
'[class.mat-primary]': 'color == "primary"',
@@ -95,7 +93,7 @@ let nextUniqueId = 0;
})
export class MatFormField implements AfterViewInit, AfterContentInit, AfterContentChecked {
- private _placeholderOptions: PlaceholderOptions;
+ private _labelOptions: LabelOptions;
/** Color of the form field underline, based on the theme. */
@Input() color: 'primary' | 'accent' | 'warn' = 'primary';
@@ -113,16 +111,16 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte
}
private _hideRequiredMarker: boolean;
- /** Override for the logic that disables the placeholder animation in certain cases. */
+ /** Override for the logic that disables the label animation in certain cases. */
private _showAlwaysAnimate = false;
/** Whether the floating label should always float or not. */
get _shouldAlwaysFloat() {
- return this._floatPlaceholder === 'always' && !this._showAlwaysAnimate;
+ return this._floatLabel === 'always' && !this._showAlwaysAnimate;
}
- /** Whether the placeholder can float or not. */
- get _canPlaceholderFloat() { return this._floatPlaceholder !== 'never'; }
+ /** Whether the label can float or not. */
+ get _canLabelFloat() { return this._floatLabel !== 'never'; }
/** State of the mat-hint and mat-error animations. */
_subscriptAnimationState: string = '';
@@ -139,23 +137,32 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte
// Unique id for the hint label.
_hintLabelId: string = `mat-hint-${nextUniqueId++}`;
- /** Whether the placeholder should always float, never float or float as the user types. */
+ /**
+ * Whether the placeholder should always float, never float or float as the user types.
+ * @deprecated Use floatLabel instead.
+ */
@Input()
- get floatPlaceholder() { return this._floatPlaceholder; }
- set floatPlaceholder(value: FloatPlaceholderType) {
- if (value !== this._floatPlaceholder) {
- this._floatPlaceholder = value || this._placeholderOptions.float || 'auto';
+ get floatPlaceholder() { return this._floatLabel; }
+ set floatPlaceholder(value: FloatLabelType) { this.floatLabel = value; }
+
+ /** Whether the label should always float, never float or float as the user types. */
+ @Input()
+ get floatLabel() { return this._floatLabel; }
+ set floatLabel(value: FloatLabelType) {
+ if (value !== this._floatLabel) {
+ this._floatLabel = value || this._labelOptions.float || 'auto';
this._changeDetectorRef.markForCheck();
}
}
- private _floatPlaceholder: FloatPlaceholderType;
+ private _floatLabel: FloatLabelType;
/** Reference to the form field's underline element. */
@ViewChild('underline') underlineRef: ElementRef;
@ViewChild('connectionContainer') _connectionContainerRef: ElementRef;
- @ViewChild('placeholder') private _placeholder: ElementRef;
+ @ViewChild('label') private _label: ElementRef;
@ContentChild(MatFormFieldControl) _control: MatFormFieldControl;
@ContentChild(MatPlaceholder) _placeholderChild: MatPlaceholder;
+ @ContentChild(MatLabel) _labelChild: MatLabel;
@ContentChildren(MatError) _errorChildren: QueryList;
@ContentChildren(MatHint) _hintChildren: QueryList;
@ContentChildren(MatPrefix) _prefixChildren: QueryList;
@@ -164,9 +171,9 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte
constructor(
public _elementRef: ElementRef,
private _changeDetectorRef: ChangeDetectorRef,
- @Optional() @Inject(MAT_PLACEHOLDER_GLOBAL_OPTIONS) placeholderOptions: PlaceholderOptions) {
- this._placeholderOptions = placeholderOptions ? placeholderOptions : {};
- this.floatPlaceholder = this._placeholderOptions.float || 'auto';
+ @Optional() @Inject(MAT_LABEL_GLOBAL_OPTIONS) labelOptions: LabelOptions) {
+ this._labelOptions = labelOptions ? labelOptions : {};
+ this.floatLabel = this._labelOptions.float || 'auto';
}
ngAfterContentInit() {
@@ -219,11 +226,27 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte
return ngControl && (ngControl as any)[prop];
}
- /** Whether the form field has a placeholder. */
_hasPlaceholder() {
return !!(this._control.placeholder || this._placeholderChild);
}
+ _hasLabel() {
+ return !!this._labelChild;
+ }
+
+ _shouldLabelFloat() {
+ return this._canLabelFloat && (this._control.shouldLabelFloat ||
+ this._control.shouldPlaceholderFloat || this._shouldAlwaysFloat);
+ }
+
+ _hideControlPlaceholder() {
+ return !this._hasLabel() || !this._shouldLabelFloat();
+ }
+
+ _hasFloatingLabel() {
+ return this._hasLabel() || this._hasPlaceholder();
+ }
+
/** Determines whether to display hints or errors. */
_getDisplayedMessages(): 'error' | 'hint' {
return (this._errorChildren && this._errorChildren.length > 0 &&
@@ -231,12 +254,12 @@ export class MatFormField implements AfterViewInit, AfterContentInit, AfterConte
}
/** Animates the placeholder up and locks it in position. */
- _animateAndLockPlaceholder(): void {
- if (this._placeholder && this._canPlaceholderFloat) {
+ _animateAndLockLabel(): void {
+ if (this._hasFloatingLabel() && this._canLabelFloat) {
this._showAlwaysAnimate = true;
- this._floatPlaceholder = 'always';
+ this._floatLabel = 'always';
- fromEvent(this._placeholder.nativeElement, 'transitionend').pipe(take(1)).subscribe(() => {
+ fromEvent(this._label.nativeElement, 'transitionend').pipe(take(1)).subscribe(() => {
this._showAlwaysAnimate = false;
});
diff --git a/src/lib/form-field/label.ts b/src/lib/form-field/label.ts
new file mode 100644
index 000000000000..a811a445f2a5
--- /dev/null
+++ b/src/lib/form-field/label.ts
@@ -0,0 +1,16 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {Directive} from '@angular/core';
+
+
+/** The floating label for a `mat-form-field`. */
+@Directive({
+ selector: 'mat-label'
+})
+export class MatLabel {}
diff --git a/src/lib/form-field/placeholder.ts b/src/lib/form-field/placeholder.ts
index aed894f09022..8c4e6f6cfff5 100644
--- a/src/lib/form-field/placeholder.ts
+++ b/src/lib/form-field/placeholder.ts
@@ -9,7 +9,7 @@
import {Directive} from '@angular/core';
-/** The floating placeholder for an `MatFormField`. */
+/** The placeholder text for an `MatFormField`. */
@Directive({
selector: 'mat-placeholder'
})
diff --git a/src/lib/form-field/public-api.ts b/src/lib/form-field/public-api.ts
index 416a3eb17e84..318a140850e1 100644
--- a/src/lib/form-field/public-api.ts
+++ b/src/lib/form-field/public-api.ts
@@ -15,4 +15,4 @@ export * from './hint';
export * from './placeholder';
export * from './prefix';
export * from './suffix';
-
+export * from './label';
diff --git a/src/lib/input/_input-theme.scss b/src/lib/input/_input-theme.scss
index 9cd15260e3c2..206b7449e2f3 100644
--- a/src/lib/input/_input-theme.scss
+++ b/src/lib/input/_input-theme.scss
@@ -2,6 +2,7 @@
@import '../core/theming/theming';
@import '../core/style/form-common';
@import '../core/typography/typography-utils';
+@import '../core/style/vendor-prefixes';
@mixin mat-input-theme($theme) {
@@ -11,6 +12,12 @@
.mat-input-element:disabled {
color: mat-color($foreground, secondary-text, if($is-dark-theme, 0.7, 0.42));
}
+
+ .mat-input-element {
+ @include input-placeholder {
+ color: _mat-control-placeholder-color($theme);
+ }
+ }
}
@mixin mat-input-typography($config) {
diff --git a/src/lib/input/input.scss b/src/lib/input/input.scss
index df6f32feacc0..65992faf949a 100644
--- a/src/lib/input/input.scss
+++ b/src/lib/input/input.scss
@@ -37,13 +37,26 @@
display: none;
}
- // Note that we can't use something like visibility: hidden or
- // display: none, because IE ends up preventing the user from
- // focusing the input altogether.
@include input-placeholder {
- // Needs to be !important, because the placeholder will end up inheriting the
- // input color in IE, if the consumer overrides it with a higher specificity.
- color: transparent !important;
+ // Delay the transition until the label has animated about a third of the way through, in
+ // order to prevent the placeholder from overlapping for a split second.
+ transition: color $swift-ease-out-duration $swift-ease-out-duration / 3
+ $swift-ease-out-timing-function;
+ }
+
+ .mat-form-field-hide-placeholder & {
+ // Note that we can't use something like visibility: hidden or
+ // display: none, because IE ends up preventing the user from
+ // focusing the input altogether.
+ @include input-placeholder {
+ // Needs to be !important, because the placeholder will end up inheriting the
+ // input color in IE, if the consumer overrides it with a higher specificity.
+ color: transparent !important;
+
+ // Remove the transition to prevent the placeholder
+ // from overlapping when the label comes back down.
+ transition: none;
+ }
}
}
diff --git a/src/lib/input/input.spec.ts b/src/lib/input/input.spec.ts
index 22d2b4cbba66..0576a067b30d 100644
--- a/src/lib/input/input.spec.ts
+++ b/src/lib/input/input.spec.ts
@@ -12,9 +12,10 @@ import {
Validators,
} from '@angular/forms';
import {
- MAT_PLACEHOLDER_GLOBAL_OPTIONS,
+ MAT_LABEL_GLOBAL_OPTIONS,
ShowOnDirtyErrorStateMatcher,
ErrorStateMatcher,
+ FloatLabelType,
} from '@angular/material/core';
import {
getMatFormFieldDuplicatedHintError,
@@ -28,7 +29,7 @@ import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {MatInputModule} from './index';
import {MatInput} from './input';
-describe('MatInput without forms', function () {
+describe('MatInput without forms', () => {
beforeEach(fakeAsync(() => {
TestBed.configureTestingModule({
imports: [
@@ -57,34 +58,35 @@ describe('MatInput without forms', function () {
MatInputPlaceholderRequiredTestComponent,
MatInputTextTestController,
MatInputWithDisabled,
- MatInputWithDynamicPlaceholder,
+ MatInputWithDynamicLabel,
MatInputWithId,
MatInputWithPrefixAndSuffix,
MatInputWithRequired,
- MatInputWithStaticPlaceholder,
+ MatInputWithStaticLabel,
MatInputWithType,
MatInputWithValueBinding,
MatInputTextareaWithBindings,
MatInputWithNgIf,
MatInputOnPush,
MatInputWithReadonlyInput,
+ MatInputWithLabelAndPlaceholder,
],
});
TestBed.compileComponents();
}));
- it('should default to floating placeholders', fakeAsync(() => {
+ it('should default to floating labels', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithId);
fixture.detectChanges();
let formField = fixture.debugElement.query(By.directive(MatFormField))
.componentInstance as MatFormField;
- expect(formField.floatPlaceholder).toBe('auto',
+ expect(formField.floatLabel).toBe('auto',
'Expected MatInput to set floatingLabel to auto by default.');
}));
- it('should default to global floating placeholder type', fakeAsync(() => {
+ it('should default to global floating label type', fakeAsync(() => {
TestBed.resetTestingModule();
TestBed.configureTestingModule({
imports: [
@@ -96,7 +98,7 @@ describe('MatInput without forms', function () {
declarations: [
MatInputWithId
],
- providers: [{ provide: MAT_PLACEHOLDER_GLOBAL_OPTIONS, useValue: { float: 'always' } }]
+ providers: [{ provide: MAT_LABEL_GLOBAL_OPTIONS, useValue: { float: 'always' } }]
});
let fixture = TestBed.createComponent(MatInputWithId);
@@ -104,8 +106,8 @@ describe('MatInput without forms', function () {
let formField = fixture.debugElement.query(By.directive(MatFormField))
.componentInstance as MatFormField;
- expect(formField.floatPlaceholder).toBe('always',
- 'Expected MatInput to set floatingLabel to always from global option.');
+ expect(formField.floatLabel).toBe('always',
+ 'Expected MatInput to set floatingLabel to always from global option.');
}));
it('should not be treated as empty if type is date',
@@ -179,7 +181,7 @@ describe('MatInput without forms', function () {
}));
it('should update the placeholder when input entered', fakeAsync(() => {
- let fixture = TestBed.createComponent(MatInputWithStaticPlaceholder);
+ let fixture = TestBed.createComponent(MatInputWithStaticLabel);
fixture.detectChanges();
let inputEl = fixture.debugElement.query(By.css('input'));
@@ -201,16 +203,14 @@ describe('MatInput without forms', function () {
it('should not be empty when the value set before view init', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithValueBinding);
fixture.detectChanges();
+ let labelEl = fixture.debugElement.query(By.css('.mat-form-field-label')).nativeElement;
- let placeholderEl =
- fixture.debugElement.query(By.css('.mat-form-field-placeholder')).nativeElement;
-
- expect(placeholderEl.classList).not.toContain('mat-form-field-empty');
+ expect(labelEl.classList).not.toContain('mat-form-field-empty');
fixture.componentInstance.value = '';
fixture.detectChanges();
- expect(placeholderEl.classList).toContain('mat-form-field-empty');
+ expect(labelEl.classList).toContain('mat-form-field-empty');
}));
it('should add id', fakeAsync(() => {
@@ -542,8 +542,8 @@ describe('MatInput without forms', function () {
expect(ariaValue).toBe(`${hintLabel.getAttribute('id')} ${endLabel.getAttribute('id')}`);
}));
- it('should float when floatPlaceholder is set to default and text is entered', fakeAsync(() => {
- let fixture = TestBed.createComponent(MatInputWithDynamicPlaceholder);
+ it('should float when floatLabel is set to default and text is entered', fakeAsync(() => {
+ let fixture = TestBed.createComponent(MatInputWithDynamicLabel);
fixture.detectChanges();
let inputEl = fixture.debugElement.query(By.css('input')).nativeElement;
@@ -568,8 +568,8 @@ describe('MatInput without forms', function () {
expect(formFieldEl.classList).toContain('mat-form-field-should-float');
}));
- it('should always float the placeholder when floatPlaceholder is set to true', fakeAsync(() => {
- let fixture = TestBed.createComponent(MatInputWithDynamicPlaceholder);
+ it('should always float the label when floatLabel is set to true', fakeAsync(() => {
+ let fixture = TestBed.createComponent(MatInputWithDynamicLabel);
fixture.detectChanges();
let inputEl = fixture.debugElement.query(By.css('input')).nativeElement;
@@ -591,8 +591,8 @@ describe('MatInput without forms', function () {
}));
- it('should never float the placeholder when floatPlaceholder is set to false', fakeAsync(() => {
- let fixture = TestBed.createComponent(MatInputWithDynamicPlaceholder);
+ it('should never float the label when floatLabel is set to false', fakeAsync(() => {
+ let fixture = TestBed.createComponent(MatInputWithDynamicLabel);
fixture.componentInstance.shouldFloat = 'never';
fixture.detectChanges();
@@ -613,23 +613,23 @@ describe('MatInput without forms', function () {
expect(labelEl.classList).not.toContain('mat-form-field-float');
}));
- it('should be able to toggle the floating placeholder programmatically', fakeAsync(() => {
+ it('should be able to toggle the floating label programmatically', fakeAsync(() => {
const fixture = TestBed.createComponent(MatInputWithId);
fixture.detectChanges();
const formField = fixture.debugElement.query(By.directive(MatFormField));
const containerInstance = formField.componentInstance as MatFormField;
- const placeholder = formField.nativeElement.querySelector('.mat-form-field-placeholder');
+ const label = formField.nativeElement.querySelector('.mat-form-field-label');
- expect(containerInstance.floatPlaceholder).toBe('auto');
- expect(placeholder.classList)
+ expect(containerInstance.floatLabel).toBe('auto');
+ expect(label.classList)
.toContain('mat-form-field-empty', 'Expected input to be considered empty.');
- containerInstance.floatPlaceholder = 'always';
+ containerInstance.floatLabel = 'always';
fixture.detectChanges();
- expect(placeholder.classList)
+ expect(label.classList)
.not.toContain('mat-form-field-empty', 'Expected input to be considered not empty.');
}));
@@ -662,15 +662,14 @@ describe('MatInput without forms', function () {
fixture.detectChanges();
let component = fixture.componentInstance;
- let placeholder =
- fixture.debugElement.query(By.css('.mat-form-field-placeholder')).nativeElement;
+ let label = fixture.debugElement.query(By.css('.mat-form-field-label')).nativeElement;
- expect(placeholder.classList).toContain('mat-form-field-empty', 'Input initially empty');
+ expect(label.classList).toContain('mat-form-field-empty', 'Input initially empty');
component.formControl.setValue('something');
fixture.detectChanges();
- expect(placeholder.classList).not.toContain('mat-form-field-empty', 'Input no longer empty');
+ expect(label.classList).not.toContain('mat-form-field-empty', 'Input no longer empty');
}));
it('should set the focused class when the input is focused', fakeAsync(() => {
@@ -689,31 +688,29 @@ describe('MatInput without forms', function () {
expect(container.classList).toContain('mat-focused');
}));
- it('should be able to animate the placeholder up and lock it in position', fakeAsync(() => {
+ it('should be able to animate the label up and lock it in position', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputTextTestController);
fixture.detectChanges();
let inputContainer = fixture.debugElement.query(By.directive(MatFormField))
.componentInstance as MatFormField;
- let placeholder = fixture.debugElement.query(By.css('.mat-input-placeholder')).nativeElement;
+ let label = fixture.debugElement.query(By.css('.mat-form-field-label')).nativeElement;
- expect(inputContainer.floatPlaceholder).toBe('auto');
+ expect(inputContainer.floatLabel).toBe('auto');
- inputContainer._animateAndLockPlaceholder();
+ inputContainer._animateAndLockLabel();
fixture.detectChanges();
expect(inputContainer._shouldAlwaysFloat).toBe(false);
- expect(inputContainer.floatPlaceholder).toBe('always');
+ expect(inputContainer.floatLabel).toBe('always');
- const fakeEvent = Object.assign(createFakeEvent('transitionend'), {
- propertyName: 'transform'
- });
+ const fakeEvent = Object.assign(createFakeEvent('transitionend'), {propertyName: 'transform'});
- placeholder.dispatchEvent(fakeEvent);
+ label.dispatchEvent(fakeEvent);
fixture.detectChanges();
expect(inputContainer._shouldAlwaysFloat).toBe(true);
- expect(inputContainer.floatPlaceholder).toBe('always');
+ expect(inputContainer.floatLabel).toBe('always');
}));
it('should not highlight when focusing a readonly input', fakeAsync(() => {
@@ -731,6 +728,57 @@ describe('MatInput without forms', function () {
expect(input.focused).toBe(false);
expect(container.classList).not.toContain('mat-focused');
}));
+
+ it('should only show the native placeholder, when there is a label, on focus', () => {
+ const fixture = TestBed.createComponent(MatInputWithLabelAndPlaceholder);
+ fixture.detectChanges();
+
+ const container = fixture.debugElement.query(By.css('mat-form-field')).nativeElement;
+ const label = fixture.debugElement.query(By.css('.mat-form-field-label')).nativeElement;
+ const input = fixture.debugElement.query(By.css('input')).nativeElement;
+
+ expect(container.classList).toContain('mat-form-field-hide-placeholder');
+ expect(container.classList).not.toContain('mat-form-field-should-float');
+ expect(label.textContent.trim()).toBe('Label');
+ expect(input.getAttribute('placeholder')).toBe('Placeholder');
+
+ input.value = 'Value';
+ fixture.detectChanges();
+
+ expect(container.classList).not.toContain('mat-form-field-hide-placeholder');
+ expect(container.classList).toContain('mat-form-field-should-float');
+ });
+
+ it('should always show the native placeholder when floatLabel is set to "always"', () => {
+ const fixture = TestBed.createComponent(MatInputWithLabelAndPlaceholder);
+
+ fixture.componentInstance.floatLabel = 'always';
+ fixture.detectChanges();
+
+ const container = fixture.debugElement.query(By.css('mat-form-field')).nativeElement;
+
+ expect(container.classList).not.toContain('mat-form-field-hide-placeholder');
+ });
+
+ it('should not show the native placeholder when floatLabel is set to "never"', () => {
+ const fixture = TestBed.createComponent(MatInputWithLabelAndPlaceholder);
+
+ fixture.componentInstance.floatLabel = 'never';
+ fixture.detectChanges();
+
+ const container = fixture.debugElement.query(By.css('mat-form-field')).nativeElement;
+ const input = fixture.debugElement.query(By.css('input')).nativeElement;
+
+ expect(container.classList).toContain('mat-form-field-hide-placeholder');
+ expect(container.classList).not.toContain('mat-form-field-should-float');
+
+ input.value = 'Value';
+ fixture.detectChanges();
+
+ expect(container.classList).toContain('mat-form-field-hide-placeholder');
+ expect(container.classList).not.toContain('mat-form-field-should-float');
+ });
+
});
describe('MatInput with forms', () => {
@@ -1237,20 +1285,20 @@ class MatInputWithValueBinding {
@Component({
template: `
-
+
`
})
-class MatInputWithStaticPlaceholder {}
+class MatInputWithStaticLabel {}
@Component({
template: `
-
+ `
})
-class MatInputWithDynamicPlaceholder {
+class MatInputWithDynamicLabel {
shouldFloat: string = 'always';
}
@@ -1373,3 +1421,15 @@ class MatInputOnPush {
`
})
class MatInputWithReadonlyInput {}
+
+@Component({
+ template: `
+
+ Label
+
+
+ `
+})
+class MatInputWithLabelAndPlaceholder {
+ floatLabel: FloatLabelType;
+}
diff --git a/src/lib/input/input.ts b/src/lib/input/input.ts
index 3491133ab338..7abed18446d9 100644
--- a/src/lib/input/input.ts
+++ b/src/lib/input/input.ts
@@ -300,7 +300,7 @@ export class MatInput implements MatFormFieldControl, OnChanges, OnDestroy,
}
// Implemented as part of MatFormFieldControl.
- get shouldPlaceholderFloat(): boolean { return this.focused || !this.empty; }
+ get shouldLabelFloat(): boolean { return this.focused || !this.empty; }
// Implemented as part of MatFormFieldControl.
setDescribedByIds(ids: string[]) { this._ariaDescribedby = ids.join(' '); }
diff --git a/src/lib/select/_select-theme.scss b/src/lib/select/_select-theme.scss
index 685f8f2b82a1..cf0d9b13d0d5 100644
--- a/src/lib/select/_select-theme.scss
+++ b/src/lib/select/_select-theme.scss
@@ -58,6 +58,10 @@
.mat-select.mat-select-disabled .mat-select-arrow {
color: mat-color($warn);
}
+
+ .mat-select-placeholder {
+ color: _mat-control-placeholder-color($theme);
+ }
}
@mixin mat-select-typography($config) {
diff --git a/src/lib/select/select.html b/src/lib/select/select.html
index eb42a39aa6d9..ebe94cefc8c1 100644
--- a/src/lib/select/select.html
+++ b/src/lib/select/select.html
@@ -4,14 +4,10 @@
(click)="toggle()"
#origin="cdkOverlayOrigin"
#trigger>
-
diff --git a/src/lib/select/select.scss b/src/lib/select/select.scss
index 7f7dd9af7f0e..7939c435dbd7 100644
--- a/src/lib/select/select.scss
+++ b/src/lib/select/select.scss
@@ -35,6 +35,7 @@ $mat-select-placeholder-arrow-space: 2 * ($mat-select-arrow-size + $mat-select-a
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
+ white-space: nowrap;
}
.mat-select-value-text {
@@ -82,7 +83,22 @@ $mat-select-placeholder-arrow-space: 2 * ($mat-select-arrow-size + $mat-select-a
cursor: pointer;
}
- .mat-form-field-placeholder {
+ .mat-form-field-label {
width: calc(100% - #{$mat-select-placeholder-arrow-space});
}
}
+
+.mat-select-placeholder {
+ // Delay the transition until the label has animated about a third of the way through, in
+ // order to prevent the placeholder from overlapping for a split second.
+ transition: color $swift-ease-out-duration $swift-ease-out-duration / 3
+ $swift-ease-out-timing-function;
+
+ .mat-form-field-hide-placeholder & {
+ color: transparent;
+
+ // Remove the transition to prevent the placeholder
+ // from overlapping when the label comes back down.
+ transition: none;
+ }
+}
diff --git a/src/lib/select/select.spec.ts b/src/lib/select/select.spec.ts
index f4b0d8c79114..e77905353d26 100644
--- a/src/lib/select/select.spec.ts
+++ b/src/lib/select/select.spec.ts
@@ -40,8 +40,8 @@ import {
} from '@angular/forms';
import {
ErrorStateMatcher,
- FloatPlaceholderType,
- MAT_PLACEHOLDER_GLOBAL_OPTIONS,
+ FloatLabelType,
+ MAT_LABEL_GLOBAL_OPTIONS,
MatOption,
} from '@angular/material/core';
import {MatFormFieldModule} from '@angular/material/form-field';
@@ -803,9 +803,9 @@ describe('MatSelect', () => {
formField = fixture.debugElement.query(By.css('.mat-form-field')).nativeElement;
}));
- it('should not float placeholder if no option is selected', fakeAsync(() => {
+ it('should not float label if no option is selected', fakeAsync(() => {
expect(formField.classList.contains('mat-form-field-should-float'))
- .toBe(false, 'placeholder should not be floating');
+ .toBe(false, 'Label should not be floating');
}));
it('should focus the first option if no option is selected', fakeAsync(() => {
@@ -936,7 +936,7 @@ describe('MatSelect', () => {
const value = fixture.debugElement.query(By.css('.mat-select-value')).nativeElement;
expect(formField.classList.contains('mat-form-field-should-float'))
- .toBe(true, 'placeholder should be floating');
+ .toBe(true, 'Label should be floating');
expect(value.textContent).toContain('Steak');
}));
@@ -1043,7 +1043,7 @@ describe('MatSelect', () => {
it('should set the view value from the form', fakeAsync(() => {
let value = fixture.debugElement.query(By.css('.mat-select-value'));
- expect(value.nativeElement.textContent.trim()).toBe('');
+ expect(value.nativeElement.textContent.trim()).toBe('Food');
fixture.componentInstance.control.setValue('pizza-1');
fixture.detectChanges();
@@ -1088,7 +1088,7 @@ describe('MatSelect', () => {
const value = fixture.debugElement.query(By.css('.mat-select-value'));
expect(value.nativeElement.textContent.trim())
- .toBe('', `Expected trigger to be cleared when option value is not found.`);
+ .toBe('Food', `Expected trigger to show the placeholder.`);
expect(trigger.textContent)
.not.toContain('Pizza', `Expected trigger is cleared when option value is not found.`);
@@ -1112,7 +1112,7 @@ describe('MatSelect', () => {
const value = fixture.debugElement.query(By.css('.mat-select-value'));
expect(value.nativeElement.textContent.trim())
- .toBe('', `Expected trigger to be cleared when option value is not found.`);
+ .toBe('Food', `Expected trigger to show the placeholder.`);
expect(trigger.textContent)
.not.toContain('Pizza', `Expected trigger is cleared when option value is not found.`);
@@ -1188,17 +1188,17 @@ describe('MatSelect', () => {
.toEqual(false, `Expected control to stay pristine after programmatic change.`);
}));
- it('should set an asterisk after the placeholder if control is required', fakeAsync(() => {
+ it('should set an asterisk after the label if control is required', fakeAsync(() => {
let requiredMarker = fixture.debugElement.query(By.css('.mat-form-field-required-marker'));
expect(requiredMarker)
- .toBeNull(`Expected placeholder not to have an asterisk, as control was not required.`);
+ .toBeNull(`Expected label not to have an asterisk, as control was not required.`);
fixture.componentInstance.isRequired = true;
fixture.detectChanges();
requiredMarker = fixture.debugElement.query(By.css('.mat-form-field-required-marker'));
expect(requiredMarker)
- .not.toBeNull(`Expected placeholder to have an asterisk, as control was required.`);
+ .not.toBeNull(`Expected label to have an asterisk, as control was required.`);
}));
});
@@ -1250,16 +1250,16 @@ describe('MatSelect', () => {
formField = fixture.debugElement.query(By.css('.mat-form-field')).nativeElement;
}));
- it('should float the placeholder when the panel is open and unselected', fakeAsync(() => {
+ it('should float the label when the panel is open and unselected', fakeAsync(() => {
expect(formField.classList.contains('mat-form-field-should-float'))
- .toBe(false, 'Expected placeholder to initially have a normal position.');
+ .toBe(false, 'Expected label to initially have a normal position.');
fixture.componentInstance.select.open();
fixture.detectChanges();
flush();
expect(formField.classList).toContain('mat-form-field-should-float',
- 'Expected placeholder to animate up to floating position.');
+ 'Expected label to animate up to floating position.');
fixture.componentInstance.select.close();
fixture.detectChanges();
@@ -1611,45 +1611,45 @@ describe('MatSelect', () => {
}));
});
- describe('with floatPlaceholder', () => {
- beforeEach(async(() => configureMatSelectTestingModule([FloatPlaceholderSelect])));
+ describe('with floatLabel', () => {
+ beforeEach(async(() => configureMatSelectTestingModule([FloatLabelSelect])));
- let fixture: ComponentFixture;
+ let fixture: ComponentFixture;
let formField: HTMLElement;
beforeEach(fakeAsync(() => {
- fixture = TestBed.createComponent(FloatPlaceholderSelect);
+ fixture = TestBed.createComponent(FloatLabelSelect);
fixture.detectChanges();
formField = fixture.debugElement.query(By.css('.mat-form-field')).nativeElement;
}));
- it('should be able to disable the floating placeholder', fakeAsync(() => {
- fixture.componentInstance.floatPlaceholder = 'never';
+ it('should be able to disable the floating label', fakeAsync(() => {
+ fixture.componentInstance.floatLabel = 'never';
fixture.detectChanges();
expect(formField.classList.contains('mat-form-field-can-float'))
- .toBe(false, 'Floating placeholder should be disabled');
+ .toBe(false, 'Floating label should be disabled');
fixture.componentInstance.control.setValue('pizza-1');
fixture.detectChanges();
expect(formField.classList.contains('mat-form-field-can-float'))
- .toBe(false, 'Floating placeholder should be disabled');
+ .toBe(false, 'Floating label should be disabled');
}));
- it('should be able to always float the placeholder', fakeAsync(() => {
+ it('should be able to always float the label', fakeAsync(() => {
expect(fixture.componentInstance.control.value).toBeFalsy();
- fixture.componentInstance.floatPlaceholder = 'always';
+ fixture.componentInstance.floatLabel = 'always';
fixture.detectChanges();
expect(formField.classList.contains('mat-form-field-can-float'))
- .toBe(true, 'Placeholder should be able to float');
+ .toBe(true, 'Label should be able to float');
expect(formField.classList.contains('mat-form-field-should-float'))
- .toBe(true, 'Placeholder should be floating');
+ .toBe(true, 'Label should be floating');
}));
- it ('should default to global floating placeholder type', fakeAsync(() => {
+ it ('should default to global floating label type', fakeAsync(() => {
fixture.destroy();
TestBed.resetTestingModule();
@@ -1662,20 +1662,20 @@ describe('MatSelect', () => {
NoopAnimationsModule
],
declarations: [
- FloatPlaceholderSelect
+ FloatLabelSelect
],
- providers: [{ provide: MAT_PLACEHOLDER_GLOBAL_OPTIONS, useValue: { float: 'always' } }]
+ providers: [{ provide: MAT_LABEL_GLOBAL_OPTIONS, useValue: { float: 'always' } }]
});
- fixture = TestBed.createComponent(FloatPlaceholderSelect);
- fixture.componentInstance.floatPlaceholder = null;
+ fixture = TestBed.createComponent(FloatLabelSelect);
+ fixture.componentInstance.floatLabel = null;
fixture.detectChanges();
formField = fixture.debugElement.query(By.css('.mat-form-field')).nativeElement;
expect(formField.classList.contains('mat-form-field-can-float'))
- .toBe(true, 'Placeholder should be able to float');
+ .toBe(true, 'Label should be able to float');
expect(formField.classList.contains('mat-form-field-should-float'))
- .toBe(true, 'Placeholder should be floating');
+ .toBe(true, 'Label should be floating');
}));
});
@@ -2231,7 +2231,7 @@ describe('MatSelect', () => {
expect(fixture.componentInstance.select.value).toBe('sandwich-2');
}));
- it('should reset the placeholder when a null value is set', fakeAsync(() => {
+ it('should reset the label when a null value is set', fakeAsync(() => {
const fixture = TestBed.createComponent(BasicSelectWithoutForms);
fixture.detectChanges();
@@ -3610,9 +3610,9 @@ class BasicSelectOnPushPreselected {
}
@Component({
- selector: 'floating-placeholder-select',
+ selector: 'floating-label-select',
template: `
-
+
{{ food.viewValue }}
@@ -3621,8 +3621,8 @@ class BasicSelectOnPushPreselected {
`,
})
-class FloatPlaceholderSelect {
- floatPlaceholder: FloatPlaceholderType | null = 'auto';
+class FloatLabelSelect {
+ floatLabel: FloatLabelType | null = 'auto';
control = new FormControl();
foods: any[] = [
{ value: 'steak-0', viewValue: 'Steak' },
diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts
index 1e652f7f94e7..ed6965cb7fe1 100644
--- a/src/lib/select/select.ts
+++ b/src/lib/select/select.ts
@@ -1214,7 +1214,7 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
}
// Implemented as part of MatFormFieldControl.
- get shouldPlaceholderFloat(): boolean {
+ get shouldLabelFloat(): boolean {
return this._panelOpen || !this.empty;
}
}
diff --git a/src/material-examples/example-module.ts b/src/material-examples/example-module.ts
index 868749123e63..1bb2111e59e8 100644
--- a/src/material-examples/example-module.ts
+++ b/src/material-examples/example-module.ts
@@ -52,7 +52,7 @@ import {MyTelInput,FormFieldCustomControlExample} from './form-field-custom-cont
import {FormFieldErrorExample} from './form-field-error/form-field-error-example';
import {FormFieldHintExample} from './form-field-hint/form-field-hint-example';
import {FormFieldOverviewExample} from './form-field-overview/form-field-overview-example';
-import {FormFieldPlaceholderExample} from './form-field-placeholder/form-field-placeholder-example';
+import {FormFieldLabelExample} from './form-field-label/form-field-label-example';
import {FormFieldPrefixSuffixExample} from './form-field-prefix-suffix/form-field-prefix-suffix-example';
import {FormFieldThemingExample} from './form-field-theming/form-field-theming-example';
import {GridListDynamicExample} from './grid-list-dynamic/grid-list-dynamic-example';
@@ -362,9 +362,9 @@ export const EXAMPLE_COMPONENTS = {
additionalFiles: null,
selectorName: null
},
- 'form-field-placeholder': {
- title: 'Form field with placeholder ',
- component: FormFieldPlaceholderExample,
+ 'form-field-label': {
+ title: 'Form field with label ',
+ component: FormFieldLabelExample,
additionalFiles: null,
selectorName: null
},
@@ -848,7 +848,7 @@ export const EXAMPLE_LIST = [
FormFieldErrorExample,
FormFieldHintExample,
FormFieldOverviewExample,
- FormFieldPlaceholderExample,
+ FormFieldLabelExample,
FormFieldPrefixSuffixExample,
FormFieldThemingExample,
GridListDynamicExample,
diff --git a/src/material-examples/form-field-custom-control/form-field-custom-control-example.ts b/src/material-examples/form-field-custom-control/form-field-custom-control-example.ts
index 4a507a8eefe3..4c07a2fadaf7 100644
--- a/src/material-examples/form-field-custom-control/form-field-custom-control-example.ts
+++ b/src/material-examples/form-field-custom-control/form-field-custom-control-example.ts
@@ -19,7 +19,7 @@ export class MyTel {
styleUrls: ['form-field-custom-control-example.css'],
providers: [{provide: MatFormFieldControl, useExisting: MyTelInput}],
host: {
- '[class.floating]': 'shouldPlaceholderFloat',
+ '[class.floating]': 'shouldLabelFloat',
'[id]': 'id',
'[attr.aria-describedby]': 'describedBy',
}
@@ -44,7 +44,7 @@ export class MyTelInput implements MatFormFieldControl, OnDestroy {
return !n.area && !n.exchange && !n.subscriber;
}
- get shouldPlaceholderFloat() {
+ get shouldLabelFloat() {
return this.focused || !this.empty;
}
diff --git a/src/material-examples/form-field-placeholder/form-field-placeholder-example.css b/src/material-examples/form-field-label/form-field-label-example.css
similarity index 100%
rename from src/material-examples/form-field-placeholder/form-field-placeholder-example.css
rename to src/material-examples/form-field-label/form-field-label-example.css
diff --git a/src/material-examples/form-field-placeholder/form-field-placeholder-example.html b/src/material-examples/form-field-label/form-field-label-example.html
similarity index 71%
rename from src/material-examples/form-field-placeholder/form-field-placeholder-example.html
rename to src/material-examples/form-field-label/form-field-label-example.html
index 01ef48d34310..0f7066bbbf0a 100644
--- a/src/material-examples/form-field-placeholder/form-field-placeholder-example.html
+++ b/src/material-examples/form-field-label/form-field-label-example.html
@@ -2,8 +2,8 @@