From d9c4d14bda01a75b57b248604acab49494c86f68 Mon Sep 17 00:00:00 2001 From: Jeremy Elbourn Date: Thu, 4 Oct 2018 17:34:44 -0700 Subject: [PATCH] fix(text-field): autosize textarea not resizing on minRows decrease Fixes #13163 --- src/cdk/text-field/autosize.spec.ts | 20 +++++++++++++++++--- src/cdk/text-field/autosize.ts | 14 +++++++++++--- src/demo-app/input/input-demo.html | 11 +++++++++++ src/demo-app/input/input-demo.scss | 4 ++++ 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/cdk/text-field/autosize.spec.ts b/src/cdk/text-field/autosize.spec.ts index a36240394b73..32fc216b371e 100644 --- a/src/cdk/text-field/autosize.spec.ts +++ b/src/cdk/text-field/autosize.spec.ts @@ -110,6 +110,22 @@ describe('CdkTextareaAutosize', () => { .toBeGreaterThan(previousMaxHeight, 'Expected increased max-height with maxRows increase.'); }); + it('should reduce textarea height when minHeight decreases', () => { + expect(textarea.style.minHeight).toBeFalsy(); + + fixture.componentInstance.minRows = 6; + fixture.detectChanges(); + + expect(textarea.style.minHeight).toBeDefined('Expected a min-height to be set via minRows.'); + + let previousHeight = parseInt(textarea.style.height!); + fixture.componentInstance.minRows = 3; + fixture.detectChanges(); + + expect(parseInt(textarea.style.height!)) + .toBeLessThan(previousHeight, 'Expected decreased height with minRows decrease.'); + }); + it('should export the cdkAutosize reference', () => { expect(fixture.componentInstance.autosize).toBeTruthy(); expect(fixture.componentInstance.autosize.resizeToFitContent).toBeTruthy(); @@ -274,9 +290,7 @@ const textareaStyleReset = ` @Component({ template: ` `, + #autosize="cdkTextareaAutosize">{{content}}`, styles: [textareaStyleReset], }) class AutosizeTextAreaWithContent { diff --git a/src/cdk/text-field/autosize.ts b/src/cdk/text-field/autosize.ts index d7b60aee7d9a..fe53763bdbc2 100644 --- a/src/cdk/text-field/autosize.ts +++ b/src/cdk/text-field/autosize.ts @@ -35,7 +35,7 @@ import {fromEvent, Subject} from 'rxjs'; }) export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy { /** Keep track of the previous textarea value to avoid resizing when the value hasn't changed. */ - private _previousValue: string; + private _previousValue?: string; private _initialHeight: string | null; private readonly _destroyed = new Subject(); @@ -43,6 +43,13 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy { private _maxRows: number; private _enabled: boolean = true; + /** + * Value of minRows as of last resize. If the minRows has decreased, the + * height of the textarea needs to be recomputed to reflect the new minimum. The maxHeight + * does not have the same problem because it does not affect the textarea's scrollHeight. + */ + private _previousMinRows: number = -1; + private _textareaElement: HTMLTextAreaElement; /** Minimum amount of rows in the textarea. */ @@ -195,8 +202,8 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy { const textarea = this._elementRef.nativeElement as HTMLTextAreaElement; const value = textarea.value; - // Only resize of the value changed since these calculations can be expensive. - if (value === this._previousValue && !force) { + // Only resize if the value or minRows have changed since these calculations can be expensive. + if (!force && this._minRows === this._previousMinRows && value === this._previousValue) { return; } @@ -238,6 +245,7 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy { } this._previousValue = value; + this._previousMinRows = this._minRows; } /** diff --git a/src/demo-app/input/input-demo.html b/src/demo-app/input/input-demo.html index d5cd364c7cc2..5defa027774d 100644 --- a/src/demo-app/input/input-demo.html +++ b/src/demo-app/input/input-demo.html @@ -543,6 +543,17 @@

Textarea

Regular <textarea>

+

Regular <textarea> with maxRows and minRows

+
+   + +
+ + +

<textarea> with mat-form-field

diff --git a/src/demo-app/input/input-demo.scss b/src/demo-app/input/input-demo.scss index ed94240ccfb9..00f861b2f63f 100644 --- a/src/demo-app/input/input-demo.scss +++ b/src/demo-app/input/input-demo.scss @@ -35,3 +35,7 @@ .demo-custom-autofill-style { @include cdk-text-field-autofill-color(transparent, red); } + +.demo-rows { + width: 30px; +}