6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
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' ;
10
18
import { 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' ;
11
23
12
24
13
25
/**
@@ -23,9 +35,10 @@ import {Platform} from '@angular/cdk/platform';
23
35
'rows' : '1' ,
24
36
} ,
25
37
} )
26
- export class MatTextareaAutosize implements AfterViewInit , DoCheck {
38
+ export class MatTextareaAutosize implements AfterViewInit , DoCheck , OnDestroy {
27
39
/** Keep track of the previous textarea value to avoid resizing when the value hasn't changed. */
28
40
private _previousValue : string ;
41
+ private _destroyed = new Subject < void > ( ) ;
29
42
30
43
private _minRows : number ;
31
44
private _maxRows : number ;
@@ -49,7 +62,12 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
49
62
/** Cached height of a textarea with a single row. */
50
63
private _cachedLineHeight : number ;
51
64
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.
53
71
54
72
/** Sets the minimum height of the textarea as determined by minRows. */
55
73
_setMinHeight ( ) : void {
@@ -74,9 +92,22 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
74
92
ngAfterViewInit ( ) {
75
93
if ( this . _platform . isBrowser ) {
76
94
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
+ }
77
103
}
78
104
}
79
105
106
+ ngOnDestroy ( ) {
107
+ this . _destroyed . next ( ) ;
108
+ this . _destroyed . complete ( ) ;
109
+ }
110
+
80
111
/** Sets a style property on the textarea element. */
81
112
private _setTextareaStyle ( property : string , value : string ) : void {
82
113
const textarea = this . _elementRef . nativeElement as HTMLTextAreaElement ;
@@ -134,8 +165,12 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
134
165
}
135
166
}
136
167
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 ) {
139
174
this . _cacheTextareaLineHeight ( ) ;
140
175
141
176
// 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 {
148
183
const value = textarea . value ;
149
184
150
185
// Only resize of the value changed since these calculations can be expensive.
151
- if ( value === this . _previousValue ) {
186
+ if ( value === this . _previousValue && ! force ) {
152
187
return ;
153
188
}
154
189
0 commit comments