66 * found in the LICENSE file at https://angular.io/license
77 */
88
9- import { Directive , ElementRef , Input , AfterViewInit , DoCheck } from '@angular/core' ;
9+ import {
10+ Directive ,
11+ ElementRef ,
12+ Input ,
13+ AfterViewInit ,
14+ DoCheck ,
15+ OnDestroy ,
16+ NgZone ,
17+ } from '@angular/core' ;
1018import { Platform } from '@angular/cdk/platform' ;
19+ import { fromEvent } from 'rxjs/observable/fromEvent' ;
20+ import { auditTime } from 'rxjs/operators/auditTime' ;
21+ import { takeUntil } from 'rxjs/operators/takeUntil' ;
22+ import { Subject } from 'rxjs/Subject' ;
1123
1224
1325/**
@@ -22,9 +34,10 @@ import {Platform} from '@angular/cdk/platform';
2234 'rows' : '1' ,
2335 } ,
2436} )
25- export class MatTextareaAutosize implements AfterViewInit , DoCheck {
37+ export class MatTextareaAutosize implements AfterViewInit , DoCheck , OnDestroy {
2638 /** Keep track of the previous textarea value to avoid resizing when the value hasn't changed. */
2739 private _previousValue : string ;
40+ private _destroyed = new Subject < void > ( ) ;
2841
2942 private _minRows : number ;
3043 private _maxRows : number ;
@@ -47,7 +60,12 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
4760 /** Cached height of a textarea with a single row. */
4861 private _cachedLineHeight : number ;
4962
50- constructor ( private _elementRef : ElementRef , private _platform : Platform ) { }
63+ constructor (
64+ private _elementRef : ElementRef ,
65+ private _platform : Platform ,
66+ private _ngZone ?: NgZone ) { }
67+
68+ // TODO(crisbeto): make the `_ngZone` a required param in the next major version.
5169
5270 /** Sets the minimum height of the textarea as determined by minRows. */
5371 _setMinHeight ( ) : void {
@@ -72,9 +90,22 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
7290 ngAfterViewInit ( ) {
7391 if ( this . _platform . isBrowser ) {
7492 this . resizeToFitContent ( ) ;
93+
94+ if ( this . _ngZone ) {
95+ this . _ngZone . runOutsideAngular ( ( ) => {
96+ fromEvent ( window , 'resize' )
97+ . pipe ( auditTime ( 16 ) , takeUntil ( this . _destroyed ) )
98+ . subscribe ( ( ) => this . resizeToFitContent ( true ) ) ;
99+ } ) ;
100+ }
75101 }
76102 }
77103
104+ ngOnDestroy ( ) {
105+ this . _destroyed . next ( ) ;
106+ this . _destroyed . complete ( ) ;
107+ }
108+
78109 /** Sets a style property on the textarea element. */
79110 private _setTextareaStyle ( property : string , value : string ) : void {
80111 const textarea = this . _elementRef . nativeElement as HTMLTextAreaElement ;
@@ -132,8 +163,12 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
132163 }
133164 }
134165
135- /** Resize the textarea to fit its content. */
136- resizeToFitContent ( ) {
166+ /**
167+ * Resize the textarea to fit its content.
168+ * @param force Whether to force a height recalculation. By default the height will be
169+ * recalculated only if the value changed since the last call.
170+ */
171+ resizeToFitContent ( force = false ) {
137172 this . _cacheTextareaLineHeight ( ) ;
138173
139174 // If we haven't determined the line-height yet, we know we're still hidden and there's no point
@@ -146,7 +181,7 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
146181 const value = textarea . value ;
147182
148183 // Only resize of the value changed since these calculations can be expensive.
149- if ( value === this . _previousValue ) {
184+ if ( value === this . _previousValue && ! force ) {
150185 return ;
151186 }
152187
0 commit comments