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/**
@@ -23,9 +35,10 @@ import {Platform} from '@angular/cdk/platform';
2335 'rows' : '1' ,
2436 } ,
2537} )
26- export class MatTextareaAutosize implements AfterViewInit , DoCheck {
38+ export class MatTextareaAutosize implements AfterViewInit , DoCheck , OnDestroy {
2739 /** Keep track of the previous textarea value to avoid resizing when the value hasn't changed. */
2840 private _previousValue : string ;
41+ private _destroyed = new Subject < void > ( ) ;
2942
3043 private _minRows : number ;
3144 private _maxRows : number ;
@@ -49,7 +62,12 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
4962 /** Cached height of a textarea with a single row. */
5063 private _cachedLineHeight : number ;
5164
52- constructor ( private _elementRef : ElementRef , private _platform : Platform ) { }
65+ constructor (
66+ private _elementRef : ElementRef ,
67+ private _platform : Platform ,
68+ private _ngZone ?: NgZone ) { }
69+
70+ // TODO(crisbeto): make the `_ngZone` a required param in the next major version.
5371
5472 /** Sets the minimum height of the textarea as determined by minRows. */
5573 _setMinHeight ( ) : void {
@@ -74,9 +92,22 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
7492 ngAfterViewInit ( ) {
7593 if ( this . _platform . isBrowser ) {
7694 this . resizeToFitContent ( ) ;
95+
96+ if ( this . _ngZone ) {
97+ this . _ngZone . runOutsideAngular ( ( ) => {
98+ fromEvent ( window , 'resize' )
99+ . pipe ( auditTime ( 16 ) , takeUntil ( this . _destroyed ) )
100+ . subscribe ( ( ) => this . resizeToFitContent ( true ) ) ;
101+ } ) ;
102+ }
77103 }
78104 }
79105
106+ ngOnDestroy ( ) {
107+ this . _destroyed . next ( ) ;
108+ this . _destroyed . complete ( ) ;
109+ }
110+
80111 /** Sets a style property on the textarea element. */
81112 private _setTextareaStyle ( property : string , value : string ) : void {
82113 const textarea = this . _elementRef . nativeElement as HTMLTextAreaElement ;
@@ -134,8 +165,12 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
134165 }
135166 }
136167
137- /** Resize the textarea to fit its content. */
138- resizeToFitContent ( ) {
168+ /**
169+ * Resize the textarea to fit its content.
170+ * @param force Whether to force a height recalculation. By default the height will be
171+ * recalculated only if the value changed since the last call.
172+ */
173+ resizeToFitContent ( force = false ) {
139174 this . _cacheTextareaLineHeight ( ) ;
140175
141176 // If we haven't determined the line-height yet, we know we're still hidden and there's no point
@@ -148,7 +183,7 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
148183 const value = textarea . value ;
149184
150185 // Only resize of the value changed since these calculations can be expensive.
151- if ( value === this . _previousValue ) {
186+ if ( value === this . _previousValue && ! force ) {
152187 return ;
153188 }
154189
0 commit comments