Skip to content

Commit

Permalink
fix(module:input): fix input autoresize (#2662)
Browse files Browse the repository at this point in the history
close #2646
  • Loading branch information
vthinkxie committed Dec 20, 2018
1 parent 36b2099 commit 0621ce8
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 10 deletions.
2 changes: 1 addition & 1 deletion components/input/demo/autosize-textarea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Component } from '@angular/core';
selector: 'nz-demo-input-autosize-textarea',
template: `
<div>
<textarea nz-input placeholder="Autosize height based on content lines" nzAutosize [(ngModel)]="value"></textarea>
<textarea nz-input placeholder="Autosize height based on content lines" ngModel nzAutosize></textarea>
<div style="margin:24px 0;"></div>
<textarea nz-input placeholder="Autosize height with minimum and maximum number of lines" [(ngModel)]="value" [nzAutosize]="{ minRows: 2, maxRows: 6 }"></textarea>
</div>
Expand Down
22 changes: 13 additions & 9 deletions components/input/nz-autoresize.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,20 @@ import {
} from '@angular/core';
import { NgControl } from '@angular/forms';
import { fromEvent, Subject } from 'rxjs';
import { auditTime, takeUntil } from 'rxjs/operators';
import { auditTime, startWith, takeUntil } from 'rxjs/operators';

export interface AutoSizeType {
minRows?: number;
maxRows?: number;
}

@Directive({
selector: 'textarea[nzAutosize]'
selector: 'textarea[nzAutosize]',
host : {
// Textarea elements that have the directive applied should have a single row by default.
// Browsers normally show two rows by default and therefore this limits the minRows binding.
rows: '1'
}
})
export class NzAutoResizeDirective implements AfterViewInit, OnDestroy {
private _autosize: boolean | AutoSizeType = false;
Expand All @@ -30,6 +35,7 @@ export class NzAutoResizeDirective implements AfterViewInit, OnDestroy {
private minRows: number;
private maxRows: number;
private destroy$ = new Subject();
private inputGap = 10;

@Input()
set nzAutosize(value: string | boolean | AutoSizeType) {
Expand Down Expand Up @@ -74,10 +80,7 @@ export class NzAutoResizeDirective implements AfterViewInit, OnDestroy {
// need to be removed temporarily.
textarea.classList.add('cdk-textarea-autosize-measuring');
textarea.placeholder = '';

// The cdk-textarea-autosize-measuring class includes a 2px padding to workaround an issue with
// Chrome, so we account for that extra space here by subtracting 4 (2px top + 2px bottom).
const height = textarea.scrollHeight - 4;
const height = Math.round((textarea.scrollHeight - this.inputGap) / this.cachedLineHeight) * this.cachedLineHeight + this.inputGap;

// Use the scrollHeight to know how large the textarea *would* be if fit its entire value.
textarea.style.height = `${height}px`;
Expand Down Expand Up @@ -134,7 +137,7 @@ export class NzAutoResizeDirective implements AfterViewInit, OnDestroy {
textareaClone.style.overflow = 'hidden';

this.el.parentNode.appendChild(textareaClone);
this.cachedLineHeight = textareaClone.clientHeight;
this.cachedLineHeight = textareaClone.clientHeight - this.inputGap - 1;
this.el.parentNode.removeChild(textareaClone);

// Min and max heights have to be re-calculated if the cached line height changes
Expand All @@ -144,7 +147,7 @@ export class NzAutoResizeDirective implements AfterViewInit, OnDestroy {

setMinHeight(): void {
const minHeight = this.minRows && this.cachedLineHeight ?
`${this.minRows * this.cachedLineHeight}px` : null;
`${this.minRows * this.cachedLineHeight + this.inputGap}px` : null;

if (minHeight) {
this.el.style.minHeight = minHeight;
Expand All @@ -153,7 +156,7 @@ export class NzAutoResizeDirective implements AfterViewInit, OnDestroy {

setMaxHeight(): void {
const maxHeight = this.maxRows && this.cachedLineHeight ?
`${this.maxRows * this.cachedLineHeight}px` : null;
`${this.maxRows * this.cachedLineHeight + this.inputGap}px` : null;

if (maxHeight) {
this.el.style.maxHeight = maxHeight;
Expand All @@ -166,6 +169,7 @@ export class NzAutoResizeDirective implements AfterViewInit, OnDestroy {
ngAfterViewInit(): void {
if (this.nzAutosize && this.platform.isBrowser) {
if (this.ngControl) {
this.resizeToFitContent();
this.ngZone.runOutsideAngular(() => {
fromEvent(window, 'resize')
.pipe(auditTime(16), takeUntil(this.destroy$))
Expand Down

0 comments on commit 0621ce8

Please sign in to comment.