From c6824d5b88c56031681435bf6099d4931ebbfbbe Mon Sep 17 00:00:00 2001 From: mmalerba Date: Tue, 3 Oct 2017 15:51:51 -0700 Subject: [PATCH] fix(input): make autosize work inside tabs & stepper (#7341) --- src/demo-app/stepper/stepper-demo.html | 10 +++++ src/demo-app/tabs/tabs-demo.html | 11 +++++ src/e2e-app/tabs/tabs-e2e.html | 4 +- src/lib/input/autosize.spec.ts | 57 +++++++++++++++++++++++++- src/lib/input/autosize.ts | 19 +++++++-- 5 files changed, 96 insertions(+), 5 deletions(-) diff --git a/src/demo-app/stepper/stepper-demo.html b/src/demo-app/stepper/stepper-demo.html index 61d8cd9cde99..4db3278b2977 100644 --- a/src/demo-app/stepper/stepper-demo.html +++ b/src/demo-app/stepper/stepper-demo.html @@ -195,3 +195,13 @@

Horizontal Stepper Demo with Templated Label

+ +

Stepper with autosize textarea

+ + + + + + + + diff --git a/src/demo-app/tabs/tabs-demo.html b/src/demo-app/tabs/tabs-demo.html index 759a92e70a9c..8b85ef763f3d 100644 --- a/src/demo-app/tabs/tabs-demo.html +++ b/src/demo-app/tabs/tabs-demo.html @@ -277,3 +277,14 @@

Tabs with background color

+ +

Tabs with autosize textarea

+ + +
+ + + +
+
+
diff --git a/src/e2e-app/tabs/tabs-e2e.html b/src/e2e-app/tabs/tabs-e2e.html index 1b21b9f58ca7..ffd4723907a1 100644 --- a/src/e2e-app/tabs/tabs-e2e.html +++ b/src/e2e-app/tabs/tabs-e2e.html @@ -2,7 +2,9 @@ One - First tab's content + + + Two diff --git a/src/lib/input/autosize.spec.ts b/src/lib/input/autosize.spec.ts index 9a4c9eda740e..b984be03340f 100644 --- a/src/lib/input/autosize.spec.ts +++ b/src/lib/input/autosize.spec.ts @@ -4,6 +4,9 @@ import {ComponentFixture, TestBed, async, fakeAsync, flushMicrotasks} from '@ang import {By} from '@angular/platform-browser'; import {MatInputModule} from './index'; import {MatTextareaAutosize} from './autosize'; +import {MatStepperModule} from '@angular/material/stepper'; +import {MatTabsModule} from '@angular/material/tabs'; +import {NoopAnimationsModule} from '@angular/platform-browser/animations'; describe('MatTextareaAutosize', () => { @@ -13,8 +16,16 @@ describe('MatTextareaAutosize', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [MatInputModule, FormsModule], + imports: [ + FormsModule, + MatInputModule, + MatStepperModule, + MatTabsModule, + NoopAnimationsModule, + ], declarations: [ + AutosizeTextareaInAStep, + AutosizeTextareaInATab, AutosizeTextAreaWithContent, AutosizeTextAreaWithValue, AutosizeTextareaWithNgModel @@ -202,6 +213,20 @@ describe('MatTextareaAutosize', () => { expect(textarea.clientHeight) .toBeGreaterThan(previousHeight, 'Expected the textarea height to have increased.'); })); + + it('should work in a tab', () => { + const fixtureWithForms = TestBed.createComponent(AutosizeTextareaInATab); + fixtureWithForms.detectChanges(); + textarea = fixtureWithForms.nativeElement.querySelector('textarea'); + expect(textarea.getBoundingClientRect().height).toBeGreaterThan(1); + }); + + it('should work in a step', () => { + const fixtureWithForms = TestBed.createComponent(AutosizeTextareaInAStep); + fixtureWithForms.detectChanges(); + textarea = fixtureWithForms.nativeElement.querySelector('textarea'); + expect(textarea.getBoundingClientRect().height).toBeGreaterThan(1); + }); }); @@ -243,3 +268,33 @@ class AutosizeTextAreaWithValue { class AutosizeTextareaWithNgModel { model = ''; } + +@Component({ + template: ` + + + + + + + + ` +}) +class AutosizeTextareaInATab {} + +@Component({ + template: ` + + + + + + + + ` +}) +class AutosizeTextareaInAStep {} diff --git a/src/lib/input/autosize.ts b/src/lib/input/autosize.ts index 3b6df9739838..51b0554f16c2 100644 --- a/src/lib/input/autosize.ts +++ b/src/lib/input/autosize.ts @@ -71,7 +71,6 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck { ngAfterViewInit() { if (this._platform.isBrowser) { - this._cacheTextareaLineHeight(); this.resizeToFitContent(); } } @@ -83,13 +82,17 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck { } /** - * Cache the height of a single-row textarea. + * Cache the height of a single-row textarea if it has not already been cached. * * We need to know how large a single "row" of a textarea is in order to apply minRows and * maxRows. For the initial version, we will assume that the height of a single line in the * textarea does not ever change. */ private _cacheTextareaLineHeight(): void { + if (this._cachedLineHeight) { + return; + } + let textarea = this._elementRef.nativeElement as HTMLTextAreaElement; // Use a clone element because we have to override some styles. @@ -124,11 +127,21 @@ export class MatTextareaAutosize implements AfterViewInit, DoCheck { } ngDoCheck() { - this.resizeToFitContent(); + if (this._platform.isBrowser) { + this.resizeToFitContent(); + } } /** Resize the textarea to fit its content. */ resizeToFitContent() { + this._cacheTextareaLineHeight(); + + // If we haven't determined the line-height yet, we know we're still hidden and there's no point + // in checking the height of the textarea. + if (!this._cachedLineHeight) { + return; + } + const textarea = this._elementRef.nativeElement as HTMLTextAreaElement; const value = textarea.value;