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
+ Optional ,
18
+ } from '@angular/core' ;
10
19
import { Platform } from '@angular/cdk/platform' ;
20
+ import { fromEvent } from 'rxjs/observable/fromEvent' ;
21
+ import { auditTime } from 'rxjs/operators/auditTime' ;
22
+ import { takeUntil } from 'rxjs/operators/takeUntil' ;
23
+ import { Subject } from 'rxjs/Subject' ;
11
24
12
25
13
26
/**
@@ -22,9 +35,10 @@ import {Platform} from '@angular/cdk/platform';
22
35
'rows' : '1' ,
23
36
} ,
24
37
} )
25
- export class MatTextareaAutosize implements AfterViewInit , DoCheck {
38
+ export class MatTextareaAutosize implements AfterViewInit , DoCheck , OnDestroy {
26
39
/** Keep track of the previous textarea value to avoid resizing when the value hasn't changed. */
27
40
private _previousValue : string ;
41
+ private _destroyed = new Subject < void > ( ) ;
28
42
29
43
private _minRows : number ;
30
44
private _maxRows : number ;
@@ -47,7 +61,10 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
47
61
/** Cached height of a textarea with a single row. */
48
62
private _cachedLineHeight : number ;
49
63
50
- constructor ( private _elementRef : ElementRef , private _platform : Platform ) { }
64
+ constructor (
65
+ private _elementRef : ElementRef ,
66
+ private _platform : Platform ,
67
+ @Optional ( ) private _ngZone ?: NgZone ) { }
51
68
52
69
/** Sets the minimum height of the textarea as determined by minRows. */
53
70
_setMinHeight ( ) : void {
@@ -72,9 +89,22 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
72
89
ngAfterViewInit ( ) {
73
90
if ( this . _platform . isBrowser ) {
74
91
this . resizeToFitContent ( ) ;
92
+
93
+ if ( this . _ngZone ) {
94
+ this . _ngZone . runOutsideAngular ( ( ) => {
95
+ fromEvent ( window , 'resize' )
96
+ . pipe ( auditTime ( 16 ) , takeUntil ( this . _destroyed ) )
97
+ . subscribe ( ( ) => this . resizeToFitContent ( true ) ) ;
98
+ } ) ;
99
+ }
75
100
}
76
101
}
77
102
103
+ ngOnDestroy ( ) {
104
+ this . _destroyed . next ( ) ;
105
+ this . _destroyed . complete ( ) ;
106
+ }
107
+
78
108
/** Sets a style property on the textarea element. */
79
109
private _setTextareaStyle ( property : string , value : string ) : void {
80
110
const textarea = this . _elementRef . nativeElement as HTMLTextAreaElement ;
@@ -132,8 +162,12 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
132
162
}
133
163
}
134
164
135
- /** Resize the textarea to fit its content. */
136
- resizeToFitContent ( ) {
165
+ /**
166
+ * Resize the textarea to fit its content.
167
+ * @param force Whether to force a height recalculation. By default the height will be
168
+ * recalculated only if the value changed since the last call.
169
+ */
170
+ resizeToFitContent ( force = false ) {
137
171
this . _cacheTextareaLineHeight ( ) ;
138
172
139
173
// If we haven't determined the line-height yet, we know we're still hidden and there's no point
@@ -146,7 +180,7 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck {
146
180
const value = textarea . value ;
147
181
148
182
// Only resize of the value changed since these calculations can be expensive.
149
- if ( value === this . _previousValue ) {
183
+ if ( value === this . _previousValue && ! force ) {
150
184
return ;
151
185
}
152
186
0 commit comments