6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
9
+ import { coerceBooleanProperty } from '@angular/cdk/coercion' ;
9
10
import {
10
11
Directive ,
11
12
ElementRef ,
@@ -35,10 +36,16 @@ import {fromEvent, Subject} from 'rxjs';
35
36
export class CdkTextareaAutosize implements AfterViewInit , DoCheck , OnDestroy {
36
37
/** Keep track of the previous textarea value to avoid resizing when the value hasn't changed. */
37
38
private _previousValue : string ;
39
+ private _initialHeight : string | null ;
38
40
private readonly _destroyed = new Subject < void > ( ) ;
39
41
40
42
private _minRows : number ;
41
43
private _maxRows : number ;
44
+ private _enabled : boolean = true ;
45
+
46
+ private get textarea ( ) : HTMLTextAreaElement {
47
+ return this . _elementRef . nativeElement as HTMLTextAreaElement ;
48
+ }
42
49
43
50
/** Minimum amount of rows in the textarea. */
44
51
@Input ( 'cdkAutosizeMinRows' )
@@ -56,6 +63,19 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
56
63
this . _setMaxHeight ( ) ;
57
64
}
58
65
66
+ /** Whether autosizing is enabled or not */
67
+ @Input ( 'cdkTextareaAutosize' )
68
+ get enabled ( ) : boolean { return this . _enabled ; }
69
+ set enabled ( value : boolean ) {
70
+ value = coerceBooleanProperty ( value ) ;
71
+
72
+ // Only act if the actual value changed. This specifically helps to not run
73
+ // resizeToFitContent too early (i.e. before ngAfterViewInit)
74
+ if ( this . _enabled !== value ) {
75
+ ( this . _enabled = value ) ? this . resizeToFitContent ( true ) : this . reset ( ) ;
76
+ }
77
+ }
78
+
59
79
/** Cached height of a textarea with a single row. */
60
80
private _cachedLineHeight : number ;
61
81
@@ -86,6 +106,9 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
86
106
87
107
ngAfterViewInit ( ) {
88
108
if ( this . _platform . isBrowser ) {
109
+ // Remember the height which we started with in case autosizing is disabled
110
+ this . _initialHeight = this . textarea . style . height ;
111
+
89
112
this . resizeToFitContent ( ) ;
90
113
91
114
this . _ngZone . runOutsideAngular ( ( ) => {
@@ -103,8 +126,7 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
103
126
104
127
/** Sets a style property on the textarea element. */
105
128
private _setTextareaStyle ( property : string , value : string ) : void {
106
- const textarea = this . _elementRef . nativeElement as HTMLTextAreaElement ;
107
- textarea . style [ property ] = value ;
129
+ this . textarea . style [ property ] = value ;
108
130
}
109
131
110
132
/**
@@ -119,10 +141,8 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
119
141
return ;
120
142
}
121
143
122
- let textarea = this . _elementRef . nativeElement as HTMLTextAreaElement ;
123
-
124
144
// Use a clone element because we have to override some styles.
125
- let textareaClone = textarea . cloneNode ( false ) as HTMLTextAreaElement ;
145
+ let textareaClone = this . textarea . cloneNode ( false ) as HTMLTextAreaElement ;
126
146
textareaClone . rows = 1 ;
127
147
128
148
// Use `position: absolute` so that this doesn't cause a browser layout and use
@@ -143,9 +163,9 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
143
163
// See Firefox bug report: https://bugzilla.mozilla.org/show_bug.cgi?id=33654
144
164
textareaClone . style . overflow = 'hidden' ;
145
165
146
- textarea . parentNode ! . appendChild ( textareaClone ) ;
166
+ this . textarea . parentNode ! . appendChild ( textareaClone ) ;
147
167
this . _cachedLineHeight = textareaClone . clientHeight ;
148
- textarea . parentNode ! . removeChild ( textareaClone ) ;
168
+ this . textarea . parentNode ! . removeChild ( textareaClone ) ;
149
169
150
170
// Min and max heights have to be re-calculated if the cached line height changes
151
171
this . _setMinHeight ( ) ;
@@ -164,6 +184,11 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
164
184
* recalculated only if the value changed since the last call.
165
185
*/
166
186
resizeToFitContent ( force : boolean = false ) {
187
+ // If autosizing is disabled, just skip everything else
188
+ if ( ! this . _enabled ) {
189
+ return ;
190
+ }
191
+
167
192
this . _cacheTextareaLineHeight ( ) ;
168
193
169
194
// If we haven't determined the line-height yet, we know we're still hidden and there's no point
@@ -211,6 +236,16 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
211
236
this . _previousValue = value ;
212
237
}
213
238
239
+ /**
240
+ * Resets the textarea to it's original size
241
+ */
242
+ reset ( ) {
243
+ if ( this . _initialHeight === undefined ) {
244
+ return ;
245
+ }
246
+ this . textarea . style . height = this . _initialHeight ;
247
+ }
248
+
214
249
_noopInputHandler ( ) {
215
250
// no-op handler that ensures we're running change detection on input events.
216
251
}
0 commit comments