Skip to content

Commit

Permalink
fix(form-field): outline gap not calculated when appearance is provid…
Browse files Browse the repository at this point in the history
…ed through DI (#12767)

Fixes the outline gap not being calculated if the `appearance` is set through the default options, because it doesn't go through the setter and we're not guaranteed for the `MutationObserver` callback to fire at the right time.

Fixes #12765.
  • Loading branch information
crisbeto authored and jelbourn committed Aug 24, 2018
1 parent 21095f5 commit 8e49388
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 10 deletions.
15 changes: 9 additions & 6 deletions src/lib/form-field/form-field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,12 @@ export class MatFormField extends _MatFormFieldMixinBase

/** The form-field appearance style. */
@Input()
get appearance(): MatFormFieldAppearance {
return this._appearance || this._defaultOptions && this._defaultOptions.appearance || 'legacy';
}
get appearance(): MatFormFieldAppearance { return this._appearance; }
set appearance(value: MatFormFieldAppearance) {
const oldValue = this._appearance;
this._appearance = value;

this._appearance = value || (this._defaults && this._defaults.appearance) || 'legacy';

if (this._appearance === 'outline' && oldValue !== value) {
// @breaking-change 7.0.0 Remove this check and else block once _ngZone is required.
if (this._ngZone) {
Expand Down Expand Up @@ -246,8 +246,8 @@ export class MatFormField extends _MatFormFieldMixinBase
private _changeDetectorRef: ChangeDetectorRef,
@Optional() @Inject(MAT_LABEL_GLOBAL_OPTIONS) labelOptions: LabelOptions,
@Optional() private _dir: Directionality,
@Optional() @Inject(MAT_FORM_FIELD_DEFAULT_OPTIONS) private _defaultOptions:
MatFormFieldDefaultOptions,
@Optional() @Inject(MAT_FORM_FIELD_DEFAULT_OPTIONS)
private _defaults: MatFormFieldDefaultOptions,
// @breaking-change 7.0.0 _platform, _ngZone and _animationMode to be made required.
private _platform?: Platform,
private _ngZone?: NgZone,
Expand All @@ -257,6 +257,9 @@ export class MatFormField extends _MatFormFieldMixinBase
this._labelOptions = labelOptions ? labelOptions : {};
this.floatLabel = this._labelOptions.float || 'auto';
this._animationsEnabled = _animationMode !== 'NoopAnimations';

// Set the default through here so we invoke the setter on the first run.
this.appearance = (_defaults && _defaults.appearance) ? _defaults.appearance : 'legacy';
}

/**
Expand Down
52 changes: 48 additions & 4 deletions src/lib/input/input.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import {Platform, PlatformModule} from '@angular/cdk/platform';
import {createFakeEvent, dispatchFakeEvent, wrappedErrorMessage} from '@angular/cdk/testing';
import {ChangeDetectionStrategy, Component, ViewChild, Type, Provider} from '@angular/core';
import {
createFakeEvent,
dispatchFakeEvent,
wrappedErrorMessage,
MockNgZone,
} from '@angular/cdk/testing';
import {ChangeDetectionStrategy, Component, ViewChild, Type, Provider, NgZone} from '@angular/core';
import {ComponentFixture, fakeAsync, flush, TestBed} from '@angular/core/testing';
import {
FormControl,
Expand Down Expand Up @@ -28,10 +33,10 @@ import {
} from '@angular/material/form-field';
import {By} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {MatInputModule} from './index';
import {MatInput} from './input';
import {MatStepperModule} from '@angular/material/stepper';
import {MatTabsModule} from '@angular/material/tabs';
import {MatInputModule} from './index';
import {MatInput} from './input';
import {MatTextareaAutosize} from './autosize';

describe('MatInput without forms', () => {
Expand Down Expand Up @@ -1170,6 +1175,35 @@ describe('MatInput with appearance', () => {
expect(parseInt(outlineGap.style.width)).toBeFalsy();
}));

it('should calculate the gaps if the default appearance is provided through DI', fakeAsync(() => {
fixture.destroy();
TestBed.resetTestingModule();

let zone: MockNgZone;
const labelFixture = createComponent(MatInputWithLabel, [
{
provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,
useValue: {appearance: 'outline'}
},
{
provide: NgZone,
useFactory: () => zone = new MockNgZone()
}
]);

labelFixture.detectChanges();
zone!.simulateZoneExit();
flush();
labelFixture.detectChanges();

const wrapperElement = labelFixture.nativeElement;
const outlineStart = wrapperElement.querySelector('.mat-form-field-outline-start');
const outlineGap = wrapperElement.querySelector('.mat-form-field-outline-gap');

expect(parseInt(outlineStart.style.width)).toBeGreaterThan(0);
expect(parseInt(outlineGap.style.width)).toBeGreaterThan(0);
}));

});

describe('MatFormField default options', () => {
Expand Down Expand Up @@ -1586,6 +1620,16 @@ class MatInputOnPush {
})
class MatInputWithReadonlyInput {}

@Component({
template: `
<mat-form-field>
<mat-label>Label</mat-label>
<input matInput>
</mat-form-field>
`
})
class MatInputWithLabel {}

@Component({
template: `
<mat-form-field [floatLabel]="floatLabel">
Expand Down

0 comments on commit 8e49388

Please sign in to comment.