From bccf8d2021157e8c2c53f54a392489c00f8d85bd Mon Sep 17 00:00:00 2001 From: Kara Date: Thu, 20 Apr 2017 15:10:49 -0700 Subject: [PATCH] fix(textarea): fix change detection error on autosize (#4180) --- src/lib/input/autosize.ts | 59 ++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/src/lib/input/autosize.ts b/src/lib/input/autosize.ts index 175a8d91e486..a274ac68673c 100644 --- a/src/lib/input/autosize.ts +++ b/src/lib/input/autosize.ts @@ -10,23 +10,36 @@ import {Directive, ElementRef, Input, AfterViewInit} from '@angular/core'; exportAs: 'mdTextareaAutosize', host: { '(input)': 'resizeToFitContent()', - '[style.min-height]': '_minHeight', - '[style.max-height]': '_maxHeight', }, }) export class MdTextareaAutosize implements AfterViewInit { + private _minRows: number; + private _maxRows: number; + /** @deprecated Use mdAutosizeMinRows */ - @Input() minRows: number; + @Input() + get minRows() { return this._minRows; } + + set minRows(value: number) { + this._minRows = value; + this._setMinHeight(); + } + + /** @deprecated Use mdAutosizeMaxRows */ + @Input() + get maxRows() { return this._maxRows; } + + set maxRows(value: number) { + this._maxRows = value; + this._setMaxHeight(); + } /** Minimum number of rows for this textarea. */ @Input() get mdAutosizeMinRows(): number { return this.minRows; } set mdAutosizeMinRows(value: number) { this.minRows = value; } - /** @deprecated Use mdAutosizeMaxRows */ - @Input() maxRows: number; - - /** Minimum number of rows for this textarea. */ + /** Maximum number of rows for this textarea. */ @Input() get mdAutosizeMaxRows(): number { return this.maxRows; } set mdAutosizeMaxRows(value: number) { this.maxRows = value; } @@ -36,14 +49,24 @@ export class MdTextareaAutosize implements AfterViewInit { constructor(private _elementRef: ElementRef) { } - /** The minimum height of the textarea as determined by minRows. */ - get _minHeight() { - return this.minRows ? `${this.minRows * this._cachedLineHeight}px` : null; + /** Sets the minimum height of the textarea as determined by minRows. */ + _setMinHeight(): void { + const minHeight = this.minRows && this._cachedLineHeight ? + `${this.minRows * this._cachedLineHeight}px` : null; + + if (minHeight) { + this._setTextareaStyle('minHeight', minHeight); + } } - /** The maximum height of the textarea as determined by maxRows. */ - get _maxHeight() { - return this.maxRows ? `${this.maxRows * this._cachedLineHeight}px` : null; + /** Sets the maximum height of the textarea as determined by maxRows. */ + _setMaxHeight(): void { + const maxHeight = this.maxRows && this._cachedLineHeight ? + `${this.maxRows * this._cachedLineHeight}px` : null; + + if (maxHeight) { + this._setTextareaStyle('maxHeight', maxHeight); + } } ngAfterViewInit() { @@ -51,6 +74,12 @@ export class MdTextareaAutosize implements AfterViewInit { this.resizeToFitContent(); } + /** Sets a style property on the textarea element. */ + private _setTextareaStyle(property: string, value: string): void { + const textarea = this._elementRef.nativeElement as HTMLTextAreaElement; + textarea.style[property] = value; + } + /** * Cache the height of a single-row textarea. * @@ -79,6 +108,10 @@ export class MdTextareaAutosize implements AfterViewInit { textarea.parentNode.appendChild(textareaClone); this._cachedLineHeight = textareaClone.clientHeight; textarea.parentNode.removeChild(textareaClone); + + // Min and max heights have to be re-calculated if the cached line height changes + this._setMinHeight(); + this._setMaxHeight(); } /** Resize the textarea to fit its content. */