Skip to content

Commit

Permalink
perf(module:input): improve input-group perf
Browse files Browse the repository at this point in the history
close #3950
  • Loading branch information
vthinkxie committed Feb 10, 2020
1 parent 86f3fa2 commit 7af643b
Show file tree
Hide file tree
Showing 21 changed files with 287 additions and 298 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,15 @@

import { Platform } from '@angular/cdk/platform';
import { AfterViewInit, Directive, DoCheck, ElementRef, Input, NgZone, OnDestroy } from '@angular/core';
import { NzDomEventService } from 'ng-zorro-antd/core';
import { Subject } from 'rxjs';
import { finalize, takeUntil } from 'rxjs/operators';

import { NzDomEventService } from 'ng-zorro-antd/core';

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

export function isAutoSizeType(value: string | boolean | AutoSizeType): value is AutoSizeType {
return typeof value !== 'string' && typeof value !== 'boolean' && (!!value.maxRows || !!value.minRows);
}

@Directive({
selector: 'textarea[nzAutosize]',
exportAs: 'nzAutosize',
Expand All @@ -40,26 +35,27 @@ export class NzAutosizeDirective implements AfterViewInit, OnDestroy, DoCheck {
private previousMinRows: number | undefined;
private minRows: number | undefined;
private maxRows: number | undefined;
private maxHeight: number | null = null;
private minHeight: number | null = null;
private destroy$ = new Subject();
private inputGap = 10;

@Input()
set nzAutosize(value: string | boolean | AutoSizeType) {
const isAutoSizeType = (data: string | boolean | AutoSizeType): data is AutoSizeType => {
return typeof data !== 'string' && typeof data !== 'boolean' && (!!data.maxRows || !!data.minRows);
};
if (typeof value === 'string') {
this.autosize = true;
} else if (isAutoSizeType(value)) {
this.autosize = value;
this.minRows = value.minRows;
this.maxRows = value.maxRows;
this.setMaxHeight();
this.setMinHeight();
this.maxHeight = this.setMaxHeight();
this.minHeight = this.setMinHeight();
}
}

get nzAutosize(): string | boolean | AutoSizeType {
return this.autosize;
}

resizeToFitContent(force: boolean = false): void {
this.cacheTextareaLineHeight();

Expand All @@ -83,13 +79,18 @@ export class NzAutosizeDirective implements AfterViewInit, OnDestroy, DoCheck {
// Long placeholders that are wider than the textarea width may lead to a bigger scrollHeight
// value. To ensure that the scrollHeight is not bigger than the content, the placeholders
// need to be removed temporarily.
textarea.classList.add('cdk-textarea-autosize-measuring');
textarea.classList.add('nz-textarea-autosize-measuring');
textarea.placeholder = '';
const height = Math.round((textarea.scrollHeight - this.inputGap) / this.cachedLineHeight) * this.cachedLineHeight + this.inputGap;

let height = Math.round((textarea.scrollHeight - this.inputGap) / this.cachedLineHeight) * this.cachedLineHeight + this.inputGap;
if (this.maxHeight !== null && height > this.maxHeight) {
height = this.maxHeight!;
}
if (this.minHeight !== null && height < this.minHeight) {
height = this.minHeight!;
}
// Use the scrollHeight to know how large the textarea *would* be if fit its entire value.
textarea.style.height = `${height}px`;
textarea.classList.remove('cdk-textarea-autosize-measuring');
textarea.classList.remove('nz-textarea-autosize-measuring');
textarea.placeholder = placeholderText;

// On Firefox resizing the textarea will prevent it from scrolling to the caret position.
Expand Down Expand Up @@ -144,28 +145,29 @@ export class NzAutosizeDirective implements AfterViewInit, OnDestroy, DoCheck {
textareaClone.style.overflow = 'hidden';

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

// Min and max heights have to be re-calculated if the cached line height changes
this.setMinHeight();
this.setMaxHeight();
this.maxHeight = this.setMaxHeight();
this.minHeight = this.setMinHeight();
}

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

if (minHeight) {
this.el.style.minHeight = minHeight;
if (minHeight !== null) {
this.el.style.minHeight = `${minHeight}px`;
}
return minHeight;
}

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

if (maxHeight) {
this.el.style.maxHeight = maxHeight;
setMaxHeight(): number | null {
const maxHeight = this.maxRows && this.cachedLineHeight ? this.maxRows * this.cachedLineHeight + this.inputGap : null;
if (maxHeight !== null) {
this.el.style.maxHeight = `${maxHeight}px`;
}
return maxHeight;
}

noopInputHandler(): void {
Expand All @@ -180,7 +182,7 @@ export class NzAutosizeDirective implements AfterViewInit, OnDestroy, DoCheck {
) {}

ngAfterViewInit(): void {
if (this.nzAutosize && this.platform.isBrowser) {
if (this.autosize && this.platform.isBrowser) {
this.resizeToFitContent();
this.nzDomEventService
.registerResizeListener()
Expand All @@ -198,7 +200,7 @@ export class NzAutosizeDirective implements AfterViewInit, OnDestroy, DoCheck {
}

ngDoCheck(): void {
if (this.nzAutosize && this.platform.isBrowser) {
if (this.autosize && this.platform.isBrowser) {
this.resizeToFitContent();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { async, ComponentFixture, fakeAsync, flush, TestBed, tick } from '@angul
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { dispatchFakeEvent, MockNgZone } from 'ng-zorro-antd/core';
import { NzAutosizeDirective } from './nz-autosize.directive';
import { NzInputModule } from './nz-input.module';
import { NzAutosizeDirective } from './autosize.directive';
import { NzInputModule } from './input.module';

describe('autoresize', () => {
let zone: MockNgZone;
Expand Down
29 changes: 18 additions & 11 deletions components/input/demo/addon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,43 @@ import { Component } from '@angular/core';
@Component({
selector: 'nz-demo-input-addon',
template: `
<div style="margin-bottom: 16px;">
<div>
<nz-input-group nzAddOnBefore="Http://" nzAddOnAfter=".com">
<input type="text" nz-input [(ngModel)]="inputValue" />
</nz-input-group>
</div>
<div style="margin-bottom: 16px;">
<div>
<nz-input-group [nzAddOnBefore]="addOnBeforeTemplate" [nzAddOnAfter]="addOnAfterTemplate">
<input type="text" nz-input [(ngModel)]="inputValue" />
</nz-input-group>
<ng-template #addOnBeforeTemplate>
<nz-select [ngModel]="'Http://'">
<nz-option [nzLabel]="'Http://'" [nzValue]="'Http://'"></nz-option>
<nz-option [nzLabel]="'Https://'" [nzValue]="'Https://'"></nz-option>
<nz-option nzLabel="Http://" nzValue="Http://"></nz-option>
<nz-option nzLabel="Https://" nzValue="Https://"></nz-option>
</nz-select>
</ng-template>
<ng-template #addOnAfterTemplate>
<nz-select [ngModel]="'.com'">
<nz-option [nzLabel]="'.com'" [nzValue]="'.com'"></nz-option>
<nz-option [nzLabel]="'.jp'" [nzValue]="'.jp'"></nz-option>
<nz-option [nzLabel]="'.cn'" [nzValue]="'.cn'"></nz-option>
<nz-option [nzLabel]="'.org'" [nzValue]="'.org'"></nz-option>
<nz-option nzLabel=".com" nzValue=".com"></nz-option>
<nz-option nzLabel=".jp" nzValue=".jp"></nz-option>
<nz-option nzLabel=".cn" nzValue=".cn"></nz-option>
<nz-option nzLabel=".org" nzValue=".org"></nz-option>
</nz-select>
</ng-template>
</div>
<div style="margin-bottom: 16px;">
<nz-input-group [nzAddOnAfterIcon]="'setting'">
<div>
<nz-input-group nzAddOnAfterIcon="setting">
<input type="text" nz-input [(ngModel)]="inputValue" />
</nz-input-group>
</div>
`
`,
styles: [
`
div {
margin-bottom: 16px;
}
`
]
})
export class NzDemoInputAddonComponent {
inputValue: string = 'my site';
Expand Down
10 changes: 1 addition & 9 deletions components/input/demo/allow-clear.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,7 @@ import { Component } from '@angular/core';
<input type="text" nz-input [(ngModel)]="inputValue" placeholder="input with clear icon" />
</nz-input-group>
<ng-template #suffixTemplate
><i
nz-icon
nz-tooltip
class="ant-input-clear-icon"
nzTheme="fill"
nzType="close-circle"
*ngIf="inputValue"
(click)="inputValue = null"
></i
><i nz-icon class="ant-input-clear-icon" nzTheme="fill" nzType="close-circle" *ngIf="inputValue" (click)="inputValue = null"></i
></ng-template>
`
})
Expand Down
18 changes: 11 additions & 7 deletions components/input/demo/autosize-textarea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@ import { Component } from '@angular/core';
selector: 'nz-demo-input-autosize-textarea',
template: `
<div>
<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 based on content lines" nzAutosize></textarea>
<textarea
nz-input
placeholder="Autosize height with minimum and maximum number of lines"
[(ngModel)]="value"
[nzAutosize]="{ minRows: 2, maxRows: 6 }"
></textarea>
<textarea nz-input placeholder="Controlled autosize" [nzAutosize]="{ minRows: 3, maxRows: 5 }"></textarea>
</div>
`
`,
styles: [
`
textarea + textarea {
margin-top: 24px;
}
`
]
})
export class NzDemoInputAutosizeTextareaComponent {
value: string;
}
export class NzDemoInputAutosizeTextareaComponent {}
12 changes: 7 additions & 5 deletions components/input/demo/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import { Component } from '@angular/core';
selector: 'nz-demo-input-group',
template: `
<nz-input-group [nzSize]="'large'">
<div nz-col nzSpan="5">
<input type="text" nz-input [ngModel]="'0571'" />
</div>
<div nz-col nzSpan="8">
<input type="text" nz-input [ngModel]="'26888888'" />
<div nz-row nzGutter="8">
<div nz-col nzSpan="5">
<input type="text" nz-input [ngModel]="'0571'" />
</div>
<div nz-col nzSpan="8">
<input type="text" nz-input [ngModel]="'26888888'" />
</div>
</div>
</nz-input-group>
<br />
Expand Down
2 changes: 1 addition & 1 deletion components/input/demo/presuffix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Component } from '@angular/core';
<input type="text" nz-input placeholder="Enter your username" />
</nz-input-group>
<ng-template #prefixTemplateUser><i nz-icon nzType="user"></i></ng-template>
<ng-template #suffixTemplateInfo><i nz-icon nz-tooltip nzTitle="Extra information" nzType="info-circle"></i></ng-template>
<ng-template #suffixTemplateInfo><i nz-icon nz-tooltip nzTooltipTitle="Extra information" nzType="info-circle"></i></ng-template>
<br />
<br />
<nz-input-group nzSuffix="RMB" nzPrefix="¥">
Expand Down
4 changes: 2 additions & 2 deletions components/input/demo/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import { Component, ElementRef, ViewChild, ViewEncapsulation } from '@angular/co
nz-input
nz-tooltip
nzTooltipTrigger="focus"
nzPlacement="topLeft"
nzTooltipPlacement="topLeft"
nzOverlayClassName="numeric-input"
[ngModel]="value"
[nzTitle]="title"
[nzTooltipTitle]="title"
placeholder="Input a number"
(ngModelChange)="onChange($event)"
(blur)="onBlur()"
Expand Down
30 changes: 30 additions & 0 deletions components/input/input-group-slot.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @license
* Copyright Alibaba.com All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/

import { ChangeDetectionStrategy, Component, Input, TemplateRef, ViewEncapsulation } from '@angular/core';

@Component({
selector: '[nz-input-group-slot]',
preserveWhitespaces: false,
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<i nz-icon [nzType]="icon" *ngIf="icon"></i>
<ng-container *nzStringTemplateOutlet="template">{{ template }}</ng-container>
`,
host: {
'[class.ant-input-group-addon]': `type === 'addon'`,
'[class.ant-input-prefix]': `type === 'prefix'`,
'[class.ant-input-suffix]': `type === 'suffix'`
}
})
export class NzInputGroupSlotComponent {
@Input() icon: string | null = null;
@Input() type: 'addon' | 'prefix' | 'suffix' | null = null;
@Input() template: string | TemplateRef<void> | null = null;
}
Loading

0 comments on commit 7af643b

Please sign in to comment.