Skip to content

Commit 8bae5b4

Browse files
jelbournjosephperrott
authored andcommitted
fix(text-field): autosize textarea not resizing on minRows decrease (#13437)
1 parent b8a6294 commit 8bae5b4

File tree

4 files changed

+43
-6
lines changed

4 files changed

+43
-6
lines changed

src/cdk/text-field/autosize.spec.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,22 @@ describe('CdkTextareaAutosize', () => {
110110
.toBeGreaterThan(previousMaxHeight, 'Expected increased max-height with maxRows increase.');
111111
});
112112

113+
it('should reduce textarea height when minHeight decreases', () => {
114+
expect(textarea.style.minHeight).toBeFalsy();
115+
116+
fixture.componentInstance.minRows = 6;
117+
fixture.detectChanges();
118+
119+
expect(textarea.style.minHeight).toBeDefined('Expected a min-height to be set via minRows.');
120+
121+
let previousHeight = parseInt(textarea.style.height!);
122+
fixture.componentInstance.minRows = 3;
123+
fixture.detectChanges();
124+
125+
expect(parseInt(textarea.style.height!))
126+
.toBeLessThan(previousHeight, 'Expected decreased height with minRows decrease.');
127+
});
128+
113129
it('should export the cdkAutosize reference', () => {
114130
expect(fixture.componentInstance.autosize).toBeTruthy();
115131
expect(fixture.componentInstance.autosize.resizeToFitContent).toBeTruthy();
@@ -275,9 +291,7 @@ const textareaStyleReset = `
275291
@Component({
276292
template: `
277293
<textarea cdkTextareaAutosize [cdkAutosizeMinRows]="minRows" [cdkAutosizeMaxRows]="maxRows"
278-
#autosize="cdkTextareaAutosize">
279-
{{content}}
280-
</textarea>`,
294+
#autosize="cdkTextareaAutosize">{{content}}</textarea>`,
281295
styles: [textareaStyleReset],
282296
})
283297
class AutosizeTextAreaWithContent {

src/cdk/text-field/autosize.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,21 @@ import {fromEvent, Subject} from 'rxjs';
3535
})
3636
export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
3737
/** Keep track of the previous textarea value to avoid resizing when the value hasn't changed. */
38-
private _previousValue: string;
38+
private _previousValue?: string;
3939
private _initialHeight: string | null;
4040
private readonly _destroyed = new Subject<void>();
4141

4242
private _minRows: number;
4343
private _maxRows: number;
4444
private _enabled: boolean = true;
4545

46+
/**
47+
* Value of minRows as of last resize. If the minRows has decreased, the
48+
* height of the textarea needs to be recomputed to reflect the new minimum. The maxHeight
49+
* does not have the same problem because it does not affect the textarea's scrollHeight.
50+
*/
51+
private _previousMinRows: number = -1;
52+
4653
private _textareaElement: HTMLTextAreaElement;
4754

4855
/** Minimum amount of rows in the textarea. */
@@ -195,8 +202,8 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
195202
const textarea = this._elementRef.nativeElement as HTMLTextAreaElement;
196203
const value = textarea.value;
197204

198-
// Only resize of the value changed since these calculations can be expensive.
199-
if (value === this._previousValue && !force) {
205+
// Only resize if the value or minRows have changed since these calculations can be expensive.
206+
if (!force && this._minRows === this._previousMinRows && value === this._previousValue) {
200207
return;
201208
}
202209

@@ -238,6 +245,7 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
238245
}
239246

240247
this._previousValue = value;
248+
this._previousMinRows = this._minRows;
241249
}
242250

243251
/**

src/demo-app/input/input-demo.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,17 @@ <h4>Textarea</h4>
543543
<h3>Regular &lt;textarea&gt;</h3>
544544
<textarea class="demo-textarea" cdkTextareaAutosize cdkAutosizeMaxRows="10"></textarea>
545545

546+
<h3>Regular &lt;textarea&gt; with maxRows and minRows</h3>
547+
<div>
548+
<label>minRows<input type="number" #minRows class="demo-rows" (input)="1+1"></label> &nbsp;
549+
<label>maxRows<input type="number" #maxRows class="demo-rows" (input)="1+1"></label>
550+
</div>
551+
<textarea class="demo-textarea"
552+
cdkTextareaAutosize
553+
[cdkAutosizeMinRows]="minRows.value"
554+
[cdkAutosizeMaxRows]="maxRows.value"></textarea>
555+
<button type="button" (click)="minRows.value = minRows.value - 1">Decrement minRows</button>
556+
546557
<h3>&lt;textarea&gt; with mat-form-field</h3>
547558
<div>
548559
<mat-form-field>

src/demo-app/input/input-demo.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,7 @@
3535
.demo-custom-autofill-style {
3636
@include cdk-text-field-autofill-color(transparent, red);
3737
}
38+
39+
.demo-rows {
40+
width: 30px;
41+
}

0 commit comments

Comments
 (0)