@@ -148,12 +148,18 @@ export class MatFormField extends _MatFormFieldMixinBase
148148 return this . _appearance || this . _defaultOptions && this . _defaultOptions . appearance || 'legacy' ;
149149 }
150150 set appearance ( value : MatFormFieldAppearance ) {
151- // If we're switching to `outline` from another appearance, we have to recalculate the gap.
152- if ( value !== this . _appearance && value === 'outline' ) {
153- this . _initialGapCalculated = false ;
154- }
155-
151+ const oldValue = this . _appearance ;
156152 this . _appearance = value ;
153+ if ( this . _appearance === 'outline' && oldValue !== value ) {
154+ // @breaking -change 7.0.0 Remove this check and else block once _ngZone is required.
155+ if ( this . _ngZone ) {
156+ this . _ngZone ! . onStable . pipe ( take ( 1 ) ) . subscribe ( ( ) => {
157+ this . _ngZone ! . runOutsideAngular ( ( ) => this . updateOutlineGap ( ) ) ;
158+ } ) ;
159+ } else {
160+ Promise . resolve ( ) . then ( ( ) => this . updateOutlineGap ( ) ) ;
161+ }
162+ }
157163 }
158164 _appearance : MatFormFieldAppearance ;
159165
@@ -217,17 +223,13 @@ export class MatFormField extends _MatFormFieldMixinBase
217223 /** Whether the Angular animations are enabled. */
218224 _animationsEnabled : boolean ;
219225
220- _outlineGapWidth = 0 ;
221- _outlineGapStart = 0 ;
222- _initialGapCalculated = false ;
223-
224226 /**
225227 * @deprecated
226228 * @breaking -change 7.0.0
227229 */
228230 @ViewChild ( 'underline' ) underlineRef : ElementRef ;
229231
230- @ViewChild ( 'connectionContainer' ) _connectionContainerRef : ElementRef ;
232+ @ViewChild ( 'connectionContainer' ) _connectionContainerRef : ElementRef < HTMLElement > ;
231233 @ViewChild ( 'inputContainer' ) _inputContainerRef : ElementRef ;
232234 @ViewChild ( 'label' ) private _label : ElementRef ;
233235 @ContentChild ( MatFormFieldControl ) _control : MatFormFieldControl < any > ;
@@ -298,20 +300,6 @@ export class MatFormField extends _MatFormFieldMixinBase
298300
299301 ngAfterContentChecked ( ) {
300302 this . _validateControlChild ( ) ;
301-
302- if ( ! this . _initialGapCalculated ) {
303- // @breaking -change 7.0.0 Remove this check and else block once _ngZone is required.
304- if ( this . _ngZone ) {
305- // It's important that we run this outside the `_ngZone`, because the `Promise.resolve`
306- // can kick us into an infinite change detection loop, if the `_initialGapCalculated`
307- // wasn't flipped on for some reason.
308- this . _ngZone . runOutsideAngular ( ( ) => {
309- Promise . resolve ( ) . then ( ( ) => this . updateOutlineGap ( ) ) ;
310- } ) ;
311- } else {
312- Promise . resolve ( ) . then ( ( ) => this . updateOutlineGap ( ) ) ;
313- }
314- }
315303 }
316304
317305 ngAfterViewInit ( ) {
@@ -422,9 +410,9 @@ export class MatFormField extends _MatFormFieldMixinBase
422410 let ids : string [ ] = [ ] ;
423411
424412 if ( this . _getDisplayedMessages ( ) === 'hint' ) {
425- let startHint = this . _hintChildren ?
413+ const startHint = this . _hintChildren ?
426414 this . _hintChildren . find ( hint => hint . align === 'start' ) : null ;
427- let endHint = this . _hintChildren ?
415+ const endHint = this . _hintChildren ?
428416 this . _hintChildren . find ( hint => hint . align === 'end' ) : null ;
429417
430418 if ( startHint ) {
@@ -456,10 +444,19 @@ export class MatFormField extends _MatFormFieldMixinBase
456444 * appearance.
457445 */
458446 updateOutlineGap ( ) {
459- if ( this . appearance === 'outline' && this . _label && this . _label . nativeElement . children . length ) {
447+ if ( this . appearance !== 'outline' ) {
448+ return ;
449+ }
450+
451+ let startWidth = 0 ;
452+ let gapWidth = 0 ;
453+ const startEls = this . _connectionContainerRef . nativeElement . querySelectorAll < HTMLElement > (
454+ '.mat-form-field-outline-start' ) ;
455+ const gapEls = this . _connectionContainerRef . nativeElement . querySelectorAll < HTMLElement > (
456+ '.mat-form-field-outline-gap' ) ;
457+ if ( this . _label && this . _label . nativeElement . children . length ) {
460458 if ( this . _platform && ! this . _platform . isBrowser ) {
461459 // getBoundingClientRect isn't available on the server.
462- this . _initialGapCalculated = true ;
463460 return ;
464461 }
465462 if ( ! document . documentElement . contains ( this . _elementRef . nativeElement ) ) {
@@ -474,14 +471,16 @@ export class MatFormField extends _MatFormFieldMixinBase
474471 for ( const child of this . _label . nativeElement . children ) {
475472 labelWidth += child . offsetWidth ;
476473 }
477- this . _outlineGapStart = labelStart - containerStart - outlineGapPadding ;
478- this . _outlineGapWidth = labelWidth * floatingLabelScale + outlineGapPadding * 2 ;
479- } else {
480- this . _outlineGapStart = 0 ;
481- this . _outlineGapWidth = 0 ;
474+ startWidth = labelStart - containerStart - outlineGapPadding ;
475+ gapWidth = labelWidth * floatingLabelScale + outlineGapPadding * 2 ;
476+ }
477+
478+ for ( let i = 0 ; i < startEls . length ; i ++ ) {
479+ startEls . item ( i ) . style . width = `${ startWidth } px` ;
480+ }
481+ for ( let i = 0 ; i < gapEls . length ; i ++ ) {
482+ gapEls . item ( i ) . style . width = `${ gapWidth } px` ;
482483 }
483- this . _initialGapCalculated = true ;
484- this . _changeDetectorRef . markForCheck ( ) ;
485484 }
486485
487486 /** Gets the start end of the rect considering the current directionality. */
0 commit comments