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
/**
@@ -22,9 +34,10 @@ import {Platform} from '@angular/cdk/platform';
22
34
'rows' : '1' ,
23
35
} ,
24
36
} )
25
- export class MatTextareaAutosize implements AfterViewInit , DoCheck {
37
+ export class MatTextareaAutosize implements AfterViewInit , DoCheck , OnDestroy {
26
38
/** Keep track of the previous textarea value to avoid resizing when the value hasn't changed. */
27
39
private _previousValue : string ;
40
+ private _destroyed = new Subject < void > ( ) ;
28
41
29
42
private _minRows : number ;
30
43
private _maxRows : number ;
@@ -47,7 +60,12 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
47
60
/** Cached height of a textarea with a single row. */
48
61
private _cachedLineHeight : number ;
49
62
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.
51
69
52
70
/** Sets the minimum height of the textarea as determined by minRows. */
53
71
_setMinHeight ( ) : void {
@@ -72,9 +90,22 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
72
90
ngAfterViewInit ( ) {
73
91
if ( this . _platform . isBrowser ) {
74
92
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
+ }
75
101
}
76
102
}
77
103
104
+ ngOnDestroy ( ) {
105
+ this . _destroyed . next ( ) ;
106
+ this . _destroyed . complete ( ) ;
107
+ }
108
+
78
109
/** Sets a style property on the textarea element. */
79
110
private _setTextareaStyle ( property : string , value : string ) : void {
80
111
const textarea = this . _elementRef . nativeElement as HTMLTextAreaElement ;
@@ -132,8 +163,12 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
132
163
}
133
164
}
134
165
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 ) {
137
172
this . _cacheTextareaLineHeight ( ) ;
138
173
139
174
// 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 {
146
181
const value = textarea . value ;
147
182
148
183
// Only resize of the value changed since these calculations can be expensive.
149
- if ( value === this . _previousValue ) {
184
+ if ( value === this . _previousValue && ! force ) {
150
185
return ;
151
186
}
152
187
0 commit comments