Skip to content

Commit

Permalink
fix(textarea): fix change detection error on autosize (#4180)
Browse files Browse the repository at this point in the history
  • Loading branch information
kara committed Apr 20, 2017
1 parent 8d0cd04 commit bccf8d2
Showing 1 changed file with 46 additions and 13 deletions.
59 changes: 46 additions & 13 deletions src/lib/input/autosize.ts
Expand Up @@ -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; }
Expand All @@ -36,21 +49,37 @@ 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() {
this._cacheTextareaLineHeight();
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.
*
Expand Down Expand Up @@ -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. */
Expand Down

0 comments on commit bccf8d2

Please sign in to comment.