Skip to content

Commit dcf010e

Browse files
committed
fix(form-field): outline gap not calculated when appearance is provided through DI
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.
1 parent 0a823dd commit dcf010e

File tree

2 files changed

+54
-9
lines changed

2 files changed

+54
-9
lines changed

src/lib/form-field/form-field.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,7 @@ export class MatFormField extends _MatFormFieldMixinBase
144144

145145
/** The form-field appearance style. */
146146
@Input()
147-
get appearance(): MatFormFieldAppearance {
148-
return this._appearance || this._defaultOptions && this._defaultOptions.appearance || 'legacy';
149-
}
147+
get appearance(): MatFormFieldAppearance { return this._appearance; }
150148
set appearance(value: MatFormFieldAppearance) {
151149
const oldValue = this._appearance;
152150
this._appearance = value;
@@ -245,8 +243,7 @@ export class MatFormField extends _MatFormFieldMixinBase
245243
private _changeDetectorRef: ChangeDetectorRef,
246244
@Optional() @Inject(MAT_LABEL_GLOBAL_OPTIONS) labelOptions: LabelOptions,
247245
@Optional() private _dir: Directionality,
248-
@Optional() @Inject(MAT_FORM_FIELD_DEFAULT_OPTIONS) private _defaultOptions:
249-
MatFormFieldDefaultOptions,
246+
@Optional() @Inject(MAT_FORM_FIELD_DEFAULT_OPTIONS) defaults: MatFormFieldDefaultOptions,
250247
// @breaking-change 7.0.0 _platform, _ngZone and _animationMode to be made required.
251248
private _platform?: Platform,
252249
private _ngZone?: NgZone,
@@ -256,6 +253,9 @@ export class MatFormField extends _MatFormFieldMixinBase
256253
this._labelOptions = labelOptions ? labelOptions : {};
257254
this.floatLabel = this._labelOptions.float || 'auto';
258255
this._animationsEnabled = _animationMode !== 'NoopAnimations';
256+
257+
// Set the default through here so we invoke the setter for the default value.
258+
this.appearance = defaults && defaults.appearance || 'legacy';
259259
}
260260

261261
/**

src/lib/input/input.spec.ts

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import {Platform, PlatformModule} from '@angular/cdk/platform';
2-
import {createFakeEvent, dispatchFakeEvent, wrappedErrorMessage} from '@angular/cdk/testing';
3-
import {ChangeDetectionStrategy, Component, ViewChild, Type, Provider} from '@angular/core';
2+
import {
3+
createFakeEvent,
4+
dispatchFakeEvent,
5+
wrappedErrorMessage,
6+
MockNgZone,
7+
} from '@angular/cdk/testing';
8+
import {ChangeDetectionStrategy, Component, ViewChild, Type, Provider, NgZone} from '@angular/core';
49
import {ComponentFixture, fakeAsync, flush, TestBed} from '@angular/core/testing';
510
import {
611
FormControl,
@@ -28,10 +33,10 @@ import {
2833
} from '@angular/material/form-field';
2934
import {By} from '@angular/platform-browser';
3035
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
31-
import {MatInputModule} from './index';
32-
import {MatInput} from './input';
3336
import {MatStepperModule} from '@angular/material/stepper';
3437
import {MatTabsModule} from '@angular/material/tabs';
38+
import {MatInputModule} from './index';
39+
import {MatInput} from './input';
3540
import {MatTextareaAutosize} from './autosize';
3641

3742
describe('MatInput without forms', () => {
@@ -1151,6 +1156,36 @@ describe('MatInput with appearance', () => {
11511156
expect(parseInt(outlineStart.style.width)).toBeGreaterThan(0);
11521157
expect(parseInt(outlineGap.style.width)).toBeGreaterThan(0);
11531158
}));
1159+
1160+
it('should calculate the gaps if the default appearance is provided through DI', fakeAsync(() => {
1161+
fixture.destroy();
1162+
TestBed.resetTestingModule();
1163+
1164+
let zone: MockNgZone;
1165+
const labelFixture = createComponent(MatInputWithLabel, [
1166+
{
1167+
provide: MAT_FORM_FIELD_DEFAULT_OPTIONS,
1168+
useValue: {appearance: 'outline'}
1169+
},
1170+
{
1171+
provide: NgZone,
1172+
useFactory: () => zone = new MockNgZone()
1173+
}
1174+
]);
1175+
1176+
labelFixture.detectChanges();
1177+
zone!.simulateZoneExit();
1178+
flush();
1179+
labelFixture.detectChanges();
1180+
1181+
const wrapperElement = labelFixture.nativeElement;
1182+
const outlineStart = wrapperElement.querySelector('.mat-form-field-outline-start');
1183+
const outlineGap = wrapperElement.querySelector('.mat-form-field-outline-gap');
1184+
1185+
expect(parseInt(outlineStart.style.width)).toBeGreaterThan(0);
1186+
expect(parseInt(outlineGap.style.width)).toBeGreaterThan(0);
1187+
}));
1188+
11541189
});
11551190

11561191
describe('MatFormField default options', () => {
@@ -1567,6 +1602,16 @@ class MatInputOnPush {
15671602
})
15681603
class MatInputWithReadonlyInput {}
15691604

1605+
@Component({
1606+
template: `
1607+
<mat-form-field>
1608+
<mat-label>Label</mat-label>
1609+
<input matInput>
1610+
</mat-form-field>
1611+
`
1612+
})
1613+
class MatInputWithLabel {}
1614+
15701615
@Component({
15711616
template: `
15721617
<mat-form-field [floatLabel]="floatLabel">

0 commit comments

Comments
 (0)