Skip to content

Commit

Permalink
fix(text-field): autosize textarea not resizing on minRows decrease (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jelbourn authored and josephperrott committed Oct 19, 2018
1 parent 3f1e960 commit cfeab79
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 6 deletions.
20 changes: 17 additions & 3 deletions src/cdk/text-field/autosize.spec.ts
Expand Up @@ -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();
Expand Down Expand Up @@ -275,9 +291,7 @@ const textareaStyleReset = `
@Component({
template: `
<textarea cdkTextareaAutosize [cdkAutosizeMinRows]="minRows" [cdkAutosizeMaxRows]="maxRows"
#autosize="cdkTextareaAutosize">
{{content}}
</textarea>`,
#autosize="cdkTextareaAutosize">{{content}}</textarea>`,
styles: [textareaStyleReset],
})
class AutosizeTextAreaWithContent {
Expand Down
14 changes: 11 additions & 3 deletions src/cdk/text-field/autosize.ts
Expand Up @@ -35,14 +35,21 @@ 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<void>();

private _minRows: number;
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. */
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -238,6 +245,7 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {
}

this._previousValue = value;
this._previousMinRows = this._minRows;
}

/**
Expand Down
11 changes: 11 additions & 0 deletions src/demo-app/input/input-demo.html
Expand Up @@ -543,6 +543,17 @@ <h4>Textarea</h4>
<h3>Regular &lt;textarea&gt;</h3>
<textarea class="demo-textarea" cdkTextareaAutosize cdkAutosizeMaxRows="10"></textarea>

<h3>Regular &lt;textarea&gt; with maxRows and minRows</h3>
<div>
<label>minRows<input type="number" #minRows class="demo-rows" (input)="1+1"></label> &nbsp;
<label>maxRows<input type="number" #maxRows class="demo-rows" (input)="1+1"></label>
</div>
<textarea class="demo-textarea"
cdkTextareaAutosize
[cdkAutosizeMinRows]="minRows.value"
[cdkAutosizeMaxRows]="maxRows.value"></textarea>
<button type="button" (click)="minRows.value = minRows.value - 1">Decrement minRows</button>

<h3>&lt;textarea&gt; with mat-form-field</h3>
<div>
<mat-form-field>
Expand Down
4 changes: 4 additions & 0 deletions src/demo-app/input/input-demo.scss
Expand Up @@ -35,3 +35,7 @@
.demo-custom-autofill-style {
@include cdk-text-field-autofill-color(transparent, red);
}

.demo-rows {
width: 30px;
}

0 comments on commit cfeab79

Please sign in to comment.