From edd410ac8426c2fde490192125a66b0074227a87 Mon Sep 17 00:00:00 2001 From: Yadong Xie Date: Wed, 16 Jun 2021 19:01:17 +0800 Subject: [PATCH] feat(module:core): support reset NZ_CONFIG inside component & overflow component (#6601) * feat(module:config): support reset NZ_CONFIG inside component * refactor: add onDestroy service * feat: add cdk entry * refactor: rebase eslint * feat: support overflow --- .../overflow}/index.ts | 0 .../overflow/overflow-container.component.ts | 163 ++++++++++++++++++ .../cdk/overflow/overflow-item.directive.ts | 46 +++++ .../cdk/overflow/overflow-rest.directive.ts | 43 +++++ .../cdk/overflow/overflow-suffix.directive.ts | 47 +++++ components/cdk/overflow/overflow.module.ts | 25 +++ components/cdk/overflow/package.json | 7 + components/cdk/overflow/public-api.ts | 10 ++ components/cdk/resize-observer/index.ts | 6 + .../resize-observer}/package.json | 0 .../resize-observer}/public-api.ts | 5 +- .../resize-observer.directive.ts | 64 +++++++ .../resize-observer/resize-observer.module.ts | 16 ++ .../resize-observer.service.ts} | 0 components/core/config/config.service.ts | 24 +-- .../resize-observers.module.ts | 13 -- components/core/services/destroy.spec.ts | 46 +++++ components/core/services/destroy.ts | 15 ++ components/core/services/public-api.ts | 1 + components/core/util/convert.ts | 2 +- .../date-picker/date-picker.component.ts | 2 +- .../page-header/page-header.component.ts | 2 +- components/select/option.component.ts | 12 +- components/select/select.component.ts | 35 ++-- components/table/src/table.module.ts | 4 +- components/table/src/table/table.component.ts | 2 +- .../table/src/table/tr-measure.component.ts | 2 +- components/tabs/tab-nav-bar.component.ts | 2 +- docs/global-config.en-US.md | 56 +++++- docs/global-config.zh-CN.md | 65 ++++++- docs/join.zh-CN.md | 14 +- package.json | 1 - scripts/site/generate-site.js | 97 +++++++---- 33 files changed, 720 insertions(+), 107 deletions(-) rename components/{core/resize-observers => cdk/overflow}/index.ts (100%) create mode 100644 components/cdk/overflow/overflow-container.component.ts create mode 100644 components/cdk/overflow/overflow-item.directive.ts create mode 100644 components/cdk/overflow/overflow-rest.directive.ts create mode 100644 components/cdk/overflow/overflow-suffix.directive.ts create mode 100644 components/cdk/overflow/overflow.module.ts create mode 100644 components/cdk/overflow/package.json create mode 100644 components/cdk/overflow/public-api.ts create mode 100644 components/cdk/resize-observer/index.ts rename components/{core/resize-observers => cdk/resize-observer}/package.json (100%) rename components/{core/resize-observers => cdk/resize-observer}/public-api.ts (55%) create mode 100644 components/cdk/resize-observer/resize-observer.directive.ts create mode 100644 components/cdk/resize-observer/resize-observer.module.ts rename components/{core/resize-observers/resize-observers.service.ts => cdk/resize-observer/resize-observer.service.ts} (100%) delete mode 100644 components/core/resize-observers/resize-observers.module.ts create mode 100644 components/core/services/destroy.spec.ts create mode 100644 components/core/services/destroy.ts diff --git a/components/core/resize-observers/index.ts b/components/cdk/overflow/index.ts similarity index 100% rename from components/core/resize-observers/index.ts rename to components/cdk/overflow/index.ts diff --git a/components/cdk/overflow/overflow-container.component.ts b/components/cdk/overflow/overflow-container.component.ts new file mode 100644 index 00000000000..0f7acaeec61 --- /dev/null +++ b/components/cdk/overflow/overflow-container.component.ts @@ -0,0 +1,163 @@ +/** + * 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 { + Component, + ChangeDetectionStrategy, + ContentChildren, + QueryList, + ElementRef, + OnInit, + AfterContentInit, + OnDestroy, + ContentChild, + ChangeDetectorRef +} from '@angular/core'; +import { BehaviorSubject, combineLatest, Observable, ReplaySubject, Subject } from 'rxjs'; +import { filter, map, pairwise, startWith, switchMap, takeUntil, withLatestFrom } from 'rxjs/operators'; + +import { NzResizeObserver } from 'ng-zorro-antd/cdk/resize-observer'; + +import { NzOverflowItemDirective } from './overflow-item.directive'; +import { NzOverflowRestDirective } from './overflow-rest.directive'; +import { NzOverflowSuffixDirective } from './overflow-suffix.directive'; + +@Component({ + selector: 'nz-overflow-container', + template: ` + + `, + providers: [NzResizeObserver], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class NzOverflowContainerComponent implements OnInit, AfterContentInit, OnDestroy { + contentInit$ = new Subject(); + @ContentChildren(NzOverflowItemDirective) + overflowItems: QueryList | undefined = undefined; + @ContentChild(NzOverflowSuffixDirective) + overflowSuffix: NzOverflowSuffixDirective | undefined = undefined; + @ContentChild(NzOverflowRestDirective) overflowRest: NzOverflowRestDirective | undefined = undefined; + overflowItems$ = new ReplaySubject>(1); + destroy$ = new Subject(); + containerWidth$ = this.nzResizeObserver + .observe(this.elementRef.nativeElement) + .pipe(map(([item]) => item.target.clientWidth || 0)); + restWidth$ = new BehaviorSubject(0); + suffixWidth$ = new BehaviorSubject(0); + suffixFixedStart$ = new BehaviorSubject(null); + displayCount$ = new BehaviorSubject(Number.MAX_SAFE_INTEGER); + restReady$ = new BehaviorSubject(false); + maxRestWith$ = this.restWidth$.pipe( + pairwise(), + map(([prevRestWidth, restWidth]) => Math.max(prevRestWidth, restWidth)) + ); + omittedItems$ = combineLatest([this.overflowItems$, this.displayCount$]).pipe( + withLatestFrom(this.contentInit$), + map(([[overflowItems, displayCount]]) => overflowItems.toArray().slice(displayCount + 1)) + ); + displayRest$ = combineLatest([this.restReady$, this.omittedItems$]).pipe( + map(([restReady, omittedItems]) => restReady && !!omittedItems.length) + ); + + updateDisplayCount(count: number, notReady?: boolean): void { + this.displayCount$.next(count); + if (this.overflowItems && !notReady) { + this.restReady$.next(count < this.overflowItems.length - 1); + } + } + + constructor( + private nzResizeObserver: NzResizeObserver, + private elementRef: ElementRef, + private cdr: ChangeDetectorRef + ) {} + + ngOnInit(): void { + const overflowItemsWidth$ = this.overflowItems$.pipe( + switchMap(items => combineLatest(items.map(item => item.itemWidth$))) + ) as Observable; + this.overflowItems$.pipe(takeUntil(this.destroy$)).subscribe(overflowItems => { + if (!overflowItems.length) { + this.displayCount$.next(0); + this.suffixFixedStart$.next(null); + } + }); + combineLatest([overflowItemsWidth$, this.containerWidth$, this.maxRestWith$, this.restWidth$, this.suffixWidth$]) + .pipe( + filter(([, containerWidth, maxRestWith]) => !!(containerWidth && maxRestWith)), + takeUntil(this.destroy$) + ) + .subscribe(([overflowItemsWidth, containerWidth, maxRestWith, restWidth, suffixWidth]) => { + let totalWidth = suffixWidth; + const len = overflowItemsWidth.length; + const lastIndex = len - 1; + for (let i = 0; i < len; i += 1) { + const currentItemWidth = overflowItemsWidth[i]; + // Break since data not ready + if (currentItemWidth === undefined) { + this.updateDisplayCount(i - 1, true); + break; + } else { + // Find best match + totalWidth += currentItemWidth; + + if ( + // Only one means `totalWidth` is the final width + (lastIndex === 0 && totalWidth <= containerWidth) || + // Last two width will be the final width + (i === lastIndex - 1 && + overflowItemsWidth[lastIndex] !== undefined && + totalWidth + overflowItemsWidth[lastIndex]! <= containerWidth) + ) { + // Additional check if match the end + this.updateDisplayCount(lastIndex); + this.suffixFixedStart$.next(null); + break; + } else if (totalWidth + maxRestWith > containerWidth) { + // Can not hold all the content to show rest + this.updateDisplayCount(i - 1); + this.suffixFixedStart$.next(totalWidth - currentItemWidth - suffixWidth + restWidth); + break; + } + this.cdr.detectChanges(); + } + } + if ( + this.overflowSuffix && + overflowItemsWidth[0] !== undefined && + overflowItemsWidth[0] + suffixWidth > containerWidth + ) { + this.suffixFixedStart$.next(null); + } + + this.cdr.detectChanges(); + }); + combineLatest([this.suffixFixedStart$, this.displayCount$]) + .pipe(takeUntil(this.destroy$)) + .subscribe(([suffixFixedStart, displayCount]) => { + this.overflowSuffix?.setSuffixStyle(suffixFixedStart, displayCount); + }); + combineLatest([this.displayCount$, this.overflowItems$]) + .pipe(takeUntil(this.destroy$)) + .subscribe(([displayCount, overflowItems]) => + overflowItems.forEach((item, index) => item.setItemStyle(index <= displayCount, index)) + ); + combineLatest([this.displayRest$, this.displayCount$]) + .pipe(takeUntil(this.destroy$)) + .subscribe(([displayRest, displayCount]) => { + this.overflowRest?.setRestStyle(displayRest, displayRest ? displayCount : Number.MAX_SAFE_INTEGER); + }); + } + ngAfterContentInit(): void { + this.overflowItems?.changes.pipe(startWith(this.overflowItems)).subscribe(this.overflowItems$); + this.overflowSuffix?.suffixWidth$.subscribe(this.suffixWidth$); + this.overflowRest?.restWidth$.subscribe(this.restWidth$); + this.contentInit$.next(); + } + ngOnDestroy(): void { + this.destroy$.next(); + this.destroy$.complete(); + } +} diff --git a/components/cdk/overflow/overflow-item.directive.ts b/components/cdk/overflow/overflow-item.directive.ts new file mode 100644 index 00000000000..18a10e2e5a2 --- /dev/null +++ b/components/cdk/overflow/overflow-item.directive.ts @@ -0,0 +1,46 @@ +/** + * 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 { ChangeDetectorRef, Directive, ElementRef } from '@angular/core'; +import { distinctUntilChanged, map, startWith, tap } from 'rxjs/operators'; + +import { NzResizeObserver } from 'ng-zorro-antd/cdk/resize-observer'; + +@Directive({ + selector: '[nzOverflowItem]', + host: { + '[style]': 'overflowStyle' + } +}) +export class NzOverflowItemDirective { + overflowStyle: { [key: string]: string | number | undefined } | undefined = undefined; + itemWidth$ = this.nzResizeObserver.observe(this.elementRef.nativeElement).pipe( + map(([item]) => (item.target as HTMLElement).offsetWidth), + distinctUntilChanged(), + startWith(undefined), + tap(width => { + this.itemWidth = width; + }) + ); + itemWidth: number | undefined = undefined; + constructor( + private nzResizeObserver: NzResizeObserver, + public elementRef: ElementRef, + private cdr: ChangeDetectorRef + ) {} + + setItemStyle(display: boolean, order: number): void { + const mergedHidden = !display; + this.overflowStyle = { + opacity: mergedHidden ? 0 : 1, + height: mergedHidden ? 0 : undefined, + overflowY: mergedHidden ? 'hidden' : undefined, + order: order, + pointerEvents: mergedHidden ? 'none' : undefined, + position: mergedHidden ? 'absolute' : undefined + }; + this.cdr.detectChanges(); + } +} diff --git a/components/cdk/overflow/overflow-rest.directive.ts b/components/cdk/overflow/overflow-rest.directive.ts new file mode 100644 index 00000000000..57fbb77e0b8 --- /dev/null +++ b/components/cdk/overflow/overflow-rest.directive.ts @@ -0,0 +1,43 @@ +/** + * 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 { ChangeDetectorRef, Directive, ElementRef } from '@angular/core'; +import { map, startWith, tap } from 'rxjs/operators'; + +import { NzResizeObserver } from 'ng-zorro-antd/cdk/resize-observer'; + +@Directive({ + selector: '[nzOverflowRest]', + host: { + '[style]': 'restStyle' + } +}) +export class NzOverflowRestDirective { + restStyle: { [key: string]: string | number | undefined } | undefined = undefined; + restWidth$ = this.nzResizeObserver.observe(this.elementRef.nativeElement).pipe( + map(([item]) => (item.target as HTMLElement).offsetWidth), + startWith(0), + tap(width => (this.restWidth = width)) + ); + restWidth = 0; + constructor( + private nzResizeObserver: NzResizeObserver, + private elementRef: ElementRef, + private cdr: ChangeDetectorRef + ) {} + + setRestStyle(display: boolean, order: number): void { + const mergedHidden = !display; + this.restStyle = { + opacity: mergedHidden ? 0 : 1, + height: mergedHidden ? 0 : undefined, + overflowY: mergedHidden ? 'hidden' : undefined, + order: order, + pointerEvents: mergedHidden ? 'none' : undefined, + position: mergedHidden ? 'absolute' : undefined + }; + this.cdr.detectChanges(); + } +} diff --git a/components/cdk/overflow/overflow-suffix.directive.ts b/components/cdk/overflow/overflow-suffix.directive.ts new file mode 100644 index 00000000000..9137d7f9187 --- /dev/null +++ b/components/cdk/overflow/overflow-suffix.directive.ts @@ -0,0 +1,47 @@ +/** + * 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 { ChangeDetectorRef, Directive, ElementRef } from '@angular/core'; +import { map, tap } from 'rxjs/operators'; + +import { NzResizeObserver } from 'ng-zorro-antd/cdk/resize-observer'; + +@Directive({ + selector: '[nzOverflowSuffix]', + host: { + '[style]': 'suffixStyle' + } +}) +export class NzOverflowSuffixDirective { + suffixStyle = {}; + suffixWidth$ = this.nzResizeObserver.observe(this.elementRef.nativeElement).pipe( + map(([item]) => (item.target as HTMLElement).offsetWidth), + tap(width => (this.suffixWidth = width)) + ); + suffixWidth = 0; + constructor( + private nzResizeObserver: NzResizeObserver, + private elementRef: ElementRef, + private cdr: ChangeDetectorRef + ) {} + + setSuffixStyle(start: number | null, order: number): void { + if (start !== null) { + this.suffixStyle = { + position: 'absolute', + left: `${start}px`, + top: 0, + opacity: 1, + order: order + }; + } else { + this.suffixStyle = { + opacity: 1, + order: order + }; + } + this.cdr.detectChanges(); + } +} diff --git a/components/cdk/overflow/overflow.module.ts b/components/cdk/overflow/overflow.module.ts new file mode 100644 index 00000000000..d93e311a9b1 --- /dev/null +++ b/components/cdk/overflow/overflow.module.ts @@ -0,0 +1,25 @@ +/** + * 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 { NgModule } from '@angular/core'; + +import { NzResizeObserverModule } from 'ng-zorro-antd/cdk/resize-observer'; + +import { NzOverflowContainerComponent } from './overflow-container.component'; +import { NzOverflowItemDirective } from './overflow-item.directive'; +import { NzOverflowRestDirective } from './overflow-rest.directive'; +import { NzOverflowSuffixDirective } from './overflow-suffix.directive'; + +@NgModule({ + imports: [NzResizeObserverModule], + declarations: [ + NzOverflowContainerComponent, + NzOverflowItemDirective, + NzOverflowRestDirective, + NzOverflowSuffixDirective + ], + exports: [NzOverflowContainerComponent, NzOverflowItemDirective, NzOverflowRestDirective, NzOverflowSuffixDirective] +}) +export class NzOverflowModule {} diff --git a/components/cdk/overflow/package.json b/components/cdk/overflow/package.json new file mode 100644 index 00000000000..ded1e7a9fdf --- /dev/null +++ b/components/cdk/overflow/package.json @@ -0,0 +1,7 @@ +{ + "ngPackage": { + "lib": { + "entryFile": "public-api.ts" + } + } +} diff --git a/components/cdk/overflow/public-api.ts b/components/cdk/overflow/public-api.ts new file mode 100644 index 00000000000..74e7db9781c --- /dev/null +++ b/components/cdk/overflow/public-api.ts @@ -0,0 +1,10 @@ +/** + * 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 + */ + +export { NzOverflowModule } from './overflow.module'; +export { NzOverflowContainerComponent } from './overflow-container.component'; +export { NzOverflowItemDirective } from './overflow-item.directive'; +export { NzOverflowRestDirective } from './overflow-rest.directive'; +export { NzOverflowSuffixDirective } from './overflow-suffix.directive'; diff --git a/components/cdk/resize-observer/index.ts b/components/cdk/resize-observer/index.ts new file mode 100644 index 00000000000..97717c1c837 --- /dev/null +++ b/components/cdk/resize-observer/index.ts @@ -0,0 +1,6 @@ +/** + * 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 + */ + +export * from './public-api'; diff --git a/components/core/resize-observers/package.json b/components/cdk/resize-observer/package.json similarity index 100% rename from components/core/resize-observers/package.json rename to components/cdk/resize-observer/package.json diff --git a/components/core/resize-observers/public-api.ts b/components/cdk/resize-observer/public-api.ts similarity index 55% rename from components/core/resize-observers/public-api.ts rename to components/cdk/resize-observer/public-api.ts index 120cf9975e3..85381c7f90e 100644 --- a/components/core/resize-observers/public-api.ts +++ b/components/cdk/resize-observer/public-api.ts @@ -3,5 +3,6 @@ * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ -export { NzResizeObserversModule } from './resize-observers.module'; -export { NzResizeObserver, NzResizeObserverFactory as ɵNzResizeObserverFactory } from './resize-observers.service'; +export { NzResizeObserverModule } from './resize-observer.module'; +export { NzResizeObserverDirective } from './resize-observer.directive'; +export { NzResizeObserver, NzResizeObserverFactory as ɵNzResizeObserverFactory } from './resize-observer.service'; diff --git a/components/cdk/resize-observer/resize-observer.directive.ts b/components/cdk/resize-observer/resize-observer.directive.ts new file mode 100644 index 00000000000..65ccc9d9208 --- /dev/null +++ b/components/cdk/resize-observer/resize-observer.directive.ts @@ -0,0 +1,64 @@ +/** + * 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 { + AfterContentInit, + Directive, + ElementRef, + EventEmitter, + Input, + OnChanges, + OnDestroy, + Output, + SimpleChanges +} from '@angular/core'; +import { Subscription } from 'rxjs'; + +import { BooleanInput } from 'ng-zorro-antd/core/types'; +import { InputBoolean } from 'ng-zorro-antd/core/util'; + +import { NzResizeObserver } from './resize-observer.service'; + +@Directive({ + selector: '[nzResizeObserver]' +}) +export class NzResizeObserverDirective implements AfterContentInit, OnDestroy, OnChanges { + static ngAcceptInputType_nzResizeObserverDisabled: BooleanInput; + @Output() readonly nzResizeObserve = new EventEmitter(); + @Input() @InputBoolean() nzResizeObserverDisabled = false; + private currentSubscription: Subscription | null = null; + + private subscribe(): void { + this.unsubscribe(); + this.currentSubscription = this.nzResizeObserver.observe(this.elementRef).subscribe(this.nzResizeObserve); + } + + private unsubscribe(): void { + this.currentSubscription?.unsubscribe(); + } + + constructor(private nzResizeObserver: NzResizeObserver, private elementRef: ElementRef) {} + + ngAfterContentInit(): void { + if (!this.currentSubscription && !this.nzResizeObserverDisabled) { + this.subscribe(); + } + } + + ngOnDestroy(): void { + this.unsubscribe(); + } + + ngOnChanges(changes: SimpleChanges): void { + const { nzResizeObserve } = changes; + if (nzResizeObserve) { + if (this.nzResizeObserverDisabled) { + this.unsubscribe(); + } else { + this.subscribe(); + } + } + } +} diff --git a/components/cdk/resize-observer/resize-observer.module.ts b/components/cdk/resize-observer/resize-observer.module.ts new file mode 100644 index 00000000000..9ca483caa15 --- /dev/null +++ b/components/cdk/resize-observer/resize-observer.module.ts @@ -0,0 +1,16 @@ +/** + * 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 { NgModule } from '@angular/core'; + +import { NzResizeObserverDirective } from './resize-observer.directive'; +import { NzResizeObserverFactory } from './resize-observer.service'; + +@NgModule({ + providers: [NzResizeObserverFactory], + declarations: [NzResizeObserverDirective], + exports: [NzResizeObserverDirective] +}) +export class NzResizeObserverModule {} diff --git a/components/core/resize-observers/resize-observers.service.ts b/components/cdk/resize-observer/resize-observer.service.ts similarity index 100% rename from components/core/resize-observers/resize-observers.service.ts rename to components/cdk/resize-observer/resize-observer.service.ts diff --git a/components/core/config/config.service.ts b/components/core/config/config.service.ts index 1d1a972d508..d8db76267e3 100644 --- a/components/core/config/config.service.ts +++ b/components/core/config/config.service.ts @@ -22,12 +22,16 @@ export class NzConfigService { private configUpdated$ = new Subject(); /** Global config holding property. */ - private config: NzConfig; + private readonly config: NzConfig; constructor(@Optional() @Inject(NZ_CONFIG) defaultConfig?: NzConfig) { this.config = defaultConfig || {}; } + getConfig(): NzConfig { + return this.config; + } + getConfigForComponent(componentName: T): NzConfig[T] { return this.config[componentName]; } @@ -58,7 +62,7 @@ export function WithConfig() { propName: NzSafeAny, originalDescriptor?: TypedPropertyDescriptor ): NzSafeAny { - const privatePropName = `$$__assignedValue__${propName}`; + const privatePropName = `$$__zorroConfigDecorator__${propName}`; Object.defineProperty(target, privatePropName, { configurable: true, @@ -69,22 +73,18 @@ export function WithConfig() { return { get(): T | undefined { const originalValue = originalDescriptor?.get ? originalDescriptor.get.bind(this)() : this[privatePropName]; - const assignedByUser = ((this.assignmentCount || {})[propName] || 0) > 1; - + const assignedByUser = (this.propertyAssignCounter?.[propName] || 0) > 1; + const configValue = this.nzConfigService.getConfigForComponent(this._nzModuleName)?.[propName]; if (assignedByUser && isDefined(originalValue)) { return originalValue; + } else { + return isDefined(configValue) ? configValue : originalValue; } - - const componentConfig = this.nzConfigService.getConfigForComponent(this._nzModuleName) || {}; - const configValue = componentConfig[propName]; - const ret = isDefined(configValue) ? configValue : originalValue; - - return ret; }, set(value?: T): void { // If the value is assigned, we consider the newly assigned value as 'assigned by user'. - this.assignmentCount = this.assignmentCount || {}; - this.assignmentCount[propName] = (this.assignmentCount[propName] || 0) + 1; + this.propertyAssignCounter = this.propertyAssignCounter || {}; + this.propertyAssignCounter[propName] = (this.propertyAssignCounter[propName] || 0) + 1; if (originalDescriptor?.set) { originalDescriptor.set.bind(this)(value!); diff --git a/components/core/resize-observers/resize-observers.module.ts b/components/core/resize-observers/resize-observers.module.ts deleted file mode 100644 index 7edb76917c3..00000000000 --- a/components/core/resize-observers/resize-observers.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * 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 { NgModule } from '@angular/core'; - -import { NzResizeObserverFactory } from './resize-observers.service'; - -@NgModule({ - providers: [NzResizeObserverFactory] -}) -export class NzResizeObserversModule {} diff --git a/components/core/services/destroy.spec.ts b/components/core/services/destroy.spec.ts new file mode 100644 index 00000000000..06c12cdea13 --- /dev/null +++ b/components/core/services/destroy.spec.ts @@ -0,0 +1,46 @@ +/** + * 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 { of } from 'rxjs'; +import { delay, finalize, takeUntil } from 'rxjs/operators'; + +import { NzDestroyService } from './destroy'; + +describe('NzDestroy service', () => { + let destroyService: NzDestroyService; + const initObservable = of('done'); + + beforeEach(() => { + destroyService = new NzDestroyService(); + }); + + it('should subscribe work normal', () => { + let result = 'initial'; + + initObservable.pipe(takeUntil(destroyService)).subscribe(value => { + result = value; + }); + + expect(result).toBe('done'); + }); + + it('should complete work normal', () => { + let result = 'initial'; + + initObservable + .pipe( + delay(1000), + takeUntil(destroyService), + finalize(() => { + result = 'done'; + }) + ) + .subscribe(); + + destroyService.ngOnDestroy(); + + expect(result).toBe('done'); + }); +}); diff --git a/components/core/services/destroy.ts b/components/core/services/destroy.ts new file mode 100644 index 00000000000..ded3cf9c85b --- /dev/null +++ b/components/core/services/destroy.ts @@ -0,0 +1,15 @@ +/** + * 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 { Injectable, OnDestroy } from '@angular/core'; +import { Subject } from 'rxjs'; + +@Injectable() +export class NzDestroyService extends Subject implements OnDestroy { + ngOnDestroy(): void { + this.next(); + this.complete(); + } +} diff --git a/components/core/services/public-api.ts b/components/core/services/public-api.ts index f880106b7d3..645559e5fb3 100644 --- a/components/core/services/public-api.ts +++ b/components/core/services/public-api.ts @@ -8,4 +8,5 @@ export * from './singleton'; export * from './drag'; export * from './scroll'; export * from './breakpoint'; +export * from './destroy'; export * from './image-preload'; diff --git a/components/core/util/convert.ts b/components/core/util/convert.ts index 218ea71bc9f..f4184646d20 100644 --- a/components/core/util/convert.ts +++ b/components/core/util/convert.ts @@ -40,7 +40,7 @@ function propDecoratorFactory( propName: string, originalDescriptor?: TypedPropertyDescriptor ): NzSafeAny { - const privatePropName = `$$__${propName}`; + const privatePropName = `$$__zorroPropDecorator__${propName}`; if (Object.prototype.hasOwnProperty.call(target, privatePropName)) { warn(`The prop "${privatePropName}" is already exist, it will be overrided by ${name} decorator.`); diff --git a/components/date-picker/date-picker.component.ts b/components/date-picker/date-picker.component.ts index 324cbedc939..8b83b558480 100644 --- a/components/date-picker/date-picker.component.ts +++ b/components/date-picker/date-picker.component.ts @@ -43,10 +43,10 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; +import { NzResizeObserver } from 'ng-zorro-antd/cdk/resize-observer'; import { slideMotion } from 'ng-zorro-antd/core/animation'; import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config'; import { NzNoAnimationDirective } from 'ng-zorro-antd/core/no-animation'; -import { NzResizeObserver } from 'ng-zorro-antd/core/resize-observers'; import { CandyDate, cloneDate, CompatibleValue, wrongSortOrder } from 'ng-zorro-antd/core/time'; import { BooleanInput, FunctionProp, NzSafeAny, OnChangeType, OnTouchedType } from 'ng-zorro-antd/core/types'; import { InputBoolean, toBoolean, valueFunctionProp } from 'ng-zorro-antd/core/util'; diff --git a/components/page-header/page-header.component.ts b/components/page-header/page-header.component.ts index 2c319615657..246c3d358f8 100644 --- a/components/page-header/page-header.component.ts +++ b/components/page-header/page-header.component.ts @@ -24,9 +24,9 @@ import { import { Subject } from 'rxjs'; import { map, takeUntil } from 'rxjs/operators'; +import { NzResizeObserver } from 'ng-zorro-antd/cdk/resize-observer'; import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config'; import { PREFIX } from 'ng-zorro-antd/core/logger'; -import { NzResizeObserver } from 'ng-zorro-antd/core/resize-observers'; import { NzPageHeaderBreadcrumbDirective, NzPageHeaderFooterDirective } from './page-header-cells'; diff --git a/components/select/option.component.ts b/components/select/option.component.ts index 7c3e0acbc33..da7d6214b56 100644 --- a/components/select/option.component.ts +++ b/components/select/option.component.ts @@ -8,7 +8,6 @@ import { Component, Input, OnChanges, - OnDestroy, OnInit, Optional, TemplateRef, @@ -18,6 +17,7 @@ import { import { Subject } from 'rxjs'; import { startWith, takeUntil } from 'rxjs/operators'; +import { NzDestroyService } from 'ng-zorro-antd/core/services'; import { BooleanInput, NzSafeAny } from 'ng-zorro-antd/core/types'; import { InputBoolean } from 'ng-zorro-antd/core/util'; @@ -28,18 +28,18 @@ import { NzOptionGroupComponent } from './option-group.component'; exportAs: 'nzOption', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, + providers: [NzDestroyService], template: ` ` }) -export class NzOptionComponent implements OnChanges, OnInit, OnDestroy { +export class NzOptionComponent implements OnChanges, OnInit { static ngAcceptInputType_nzDisabled: BooleanInput; static ngAcceptInputType_nzHide: BooleanInput; static ngAcceptInputType_nzCustomContent: BooleanInput; - private destroy$ = new Subject(); changes = new Subject(); groupLabel: string | number | TemplateRef | null = null; @ViewChild(TemplateRef, { static: true }) template!: TemplateRef; @@ -49,7 +49,7 @@ export class NzOptionComponent implements OnChanges, OnInit, OnDestroy { @Input() @InputBoolean() nzHide = false; @Input() @InputBoolean() nzCustomContent = false; - constructor(@Optional() private nzOptionGroupComponent: NzOptionGroupComponent) {} + constructor(@Optional() private nzOptionGroupComponent: NzOptionGroupComponent, private destroy$: NzDestroyService) {} ngOnInit(): void { if (this.nzOptionGroupComponent) { @@ -62,8 +62,4 @@ export class NzOptionComponent implements OnChanges, OnInit, OnDestroy { ngOnChanges(): void { this.changes.next(); } - ngOnDestroy(): void { - this.destroy$.next(); - this.destroy$.complete(); - } } diff --git a/components/select/select.component.ts b/components/select/select.component.ts index bace26af270..af84d1def47 100644 --- a/components/select/select.component.ts +++ b/components/select/select.component.ts @@ -31,13 +31,14 @@ import { ViewEncapsulation } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { BehaviorSubject, combineLatest, merge, Subject } from 'rxjs'; +import { BehaviorSubject, combineLatest, merge } from 'rxjs'; import { startWith, switchMap, takeUntil } from 'rxjs/operators'; import { slideMotion } from 'ng-zorro-antd/core/animation'; import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config'; import { NzNoAnimationDirective } from 'ng-zorro-antd/core/no-animation'; import { reqAnimFrame } from 'ng-zorro-antd/core/polyfill'; +import { NzDestroyService } from 'ng-zorro-antd/core/services'; import { BooleanInput, NzSafeAny, OnChangeType, OnTouchedType } from 'ng-zorro-antd/core/types'; import { InputBoolean, isNotNil } from 'ng-zorro-antd/core/util'; @@ -63,6 +64,7 @@ export type NzSelectSizeType = 'large' | 'default' | 'small'; exportAs: 'nzSelect', preserveWhitespaces: false, providers: [ + NzDestroyService, { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NzSelectComponent), @@ -162,7 +164,7 @@ export type NzSelectSizeType = 'large' | 'default' | 'small'; '(click)': 'onHostClick()' } }) -export class NzSelectComponent implements ControlValueAccessor, OnInit, OnDestroy, AfterContentInit, OnChanges { +export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterContentInit, OnChanges, OnDestroy { readonly _nzModuleName: NzConfigKey = NZ_CONFIG_MODULE_NAME; static ngAcceptInputType_nzAllowClear: BooleanInput; @@ -239,7 +241,6 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, OnDestro private searchValue: string = ''; private isReactiveDriven = false; private value: NzSafeAny | NzSafeAny[]; - private destroy$ = new Subject(); private _nzShowArrow: boolean | undefined; onChange: OnChangeType = () => {}; onTouched: OnTouchedType = () => {}; @@ -504,6 +505,7 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, OnDestro } constructor( + private destroy$: NzDestroyService, public nzConfigService: NzConfigService, private cdr: ChangeDetectorRef, private elementRef: ElementRef, @@ -563,17 +565,19 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, OnDestro if (nzOptions) { this.isReactiveDriven = true; const listOfOptions = this.nzOptions || []; - const listOfTransformedItem = listOfOptions.map(item => ({ - template: item.label instanceof TemplateRef ? item.label : null, - nzLabel: typeof item.label === 'string' || typeof item.label === 'number' ? item.label : null, - nzValue: item.value, - nzDisabled: item.disabled || false, - nzHide: item.hide || false, - nzCustomContent: item.label instanceof TemplateRef, - groupLabel: item.groupLabel || null, - type: 'item', - key: item.value - })); + const listOfTransformedItem = listOfOptions.map(item => { + return { + template: item.label instanceof TemplateRef ? item.label : null, + nzLabel: typeof item.label === 'string' || typeof item.label === 'number' ? item.label : null, + nzValue: item.value, + nzDisabled: item.disabled || false, + nzHide: item.hide || false, + nzCustomContent: item.label instanceof TemplateRef, + groupLabel: item.groupLabel || null, + type: 'item', + key: item.value + }; + }); this.listOfTemplateItem$.next(listOfTransformedItem); } } @@ -667,10 +671,7 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, OnDestro }); } } - ngOnDestroy(): void { this.focusMonitor.stopMonitoring(this.elementRef); - this.destroy$.next(); - this.destroy$.complete(); } } diff --git a/components/table/src/table.module.ts b/components/table/src/table.module.ts index 2dcca3ddce0..48617c992f6 100644 --- a/components/table/src/table.module.ts +++ b/components/table/src/table.module.ts @@ -11,9 +11,9 @@ import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { NzButtonModule } from 'ng-zorro-antd/button'; +import { NzResizeObserverModule } from 'ng-zorro-antd/cdk/resize-observer'; import { NzCheckboxModule } from 'ng-zorro-antd/checkbox'; import { NzOutletModule } from 'ng-zorro-antd/core/outlet'; -import { NzResizeObserversModule } from 'ng-zorro-antd/core/resize-observers'; import { NzDropDownModule } from 'ng-zorro-antd/dropdown'; import { NzEmptyModule } from 'ng-zorro-antd/empty'; import { NzI18nModule } from 'ng-zorro-antd/i18n'; @@ -112,7 +112,7 @@ import { NzTrDirective } from './table/tr.directive'; CommonModule, PlatformModule, NzPaginationModule, - NzResizeObserversModule, + NzResizeObserverModule, NzSpinModule, NzI18nModule, NzIconModule, diff --git a/components/table/src/table/table.component.ts b/components/table/src/table/table.component.ts index e76b55fc19d..2fd94d530ac 100644 --- a/components/table/src/table/table.component.ts +++ b/components/table/src/table/table.component.ts @@ -28,8 +28,8 @@ import { import { BehaviorSubject, combineLatest, Subject } from 'rxjs'; import { filter, map, takeUntil } from 'rxjs/operators'; +import { NzResizeObserver } from 'ng-zorro-antd/cdk/resize-observer'; import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config'; -import { NzResizeObserver } from 'ng-zorro-antd/core/resize-observers'; import { BooleanInput, NzSafeAny } from 'ng-zorro-antd/core/types'; import { InputBoolean, measureScrollbar } from 'ng-zorro-antd/core/util'; import { PaginationItemRenderContext } from 'ng-zorro-antd/pagination'; diff --git a/components/table/src/table/tr-measure.component.ts b/components/table/src/table/tr-measure.component.ts index 11953863c65..9a634870a1b 100644 --- a/components/table/src/table/tr-measure.component.ts +++ b/components/table/src/table/tr-measure.component.ts @@ -22,7 +22,7 @@ import { import { combineLatest, Observable, Subject } from 'rxjs'; import { debounceTime, map, startWith, switchMap, takeUntil } from 'rxjs/operators'; -import { NzResizeObserver } from 'ng-zorro-antd/core/resize-observers'; +import { NzResizeObserver } from 'ng-zorro-antd/cdk/resize-observer'; @Component({ selector: 'tr[nz-table-measure-row]', diff --git a/components/tabs/tab-nav-bar.component.ts b/components/tabs/tab-nav-bar.component.ts index 48128e8bccb..4b0b1b53f4c 100644 --- a/components/tabs/tab-nav-bar.component.ts +++ b/components/tabs/tab-nav-bar.component.ts @@ -32,8 +32,8 @@ import { import { animationFrameScheduler, asapScheduler, merge, of, Subject } from 'rxjs'; import { auditTime, takeUntil } from 'rxjs/operators'; +import { NzResizeObserver } from 'ng-zorro-antd/cdk/resize-observer'; import { reqAnimFrame } from 'ng-zorro-antd/core/polyfill'; -import { NzResizeObserver } from 'ng-zorro-antd/core/resize-observers'; import { NumberInput, NzSafeAny } from 'ng-zorro-antd/core/types'; import { NzTabPositionMode, NzTabScrollEvent, NzTabScrollListOffsetEvent } from './interfaces'; diff --git a/docs/global-config.en-US.md b/docs/global-config.en-US.md index 67cdafad0cb..49314cd8ef8 100644 --- a/docs/global-config.en-US.md +++ b/docs/global-config.en-US.md @@ -103,6 +103,60 @@ const nzConfigFactory = ( export class AppModule {} ``` + +## Overwrite inside Component + +Developers can use Dependency Injection to reset `NZ_CONFIG` within a particular component, which will not affect configurations outside it. + +```typescript +@Component({ + providers: [ + // reset local NzConfigService + NzConfigService, + { + provide: NZ_CONFIG, + useValue: { + button: { + nzSize: 'large' + } + } + } + ] +}) +``` + +You can also use `useFactory` to combine the global configuration with the local configuration to take effect + +> Note: Change global configuration after component initialization won't affect local configuration + +```typescript +@Component({ + providers: [ + // reset local NzConfigService + NzConfigService, + { + provide: NZ_CONFIG, + useFactory: (nzConfigService: NzConfigService) => { + const globalConfig = nzConfigService.getConfig(); + const localConfig = { + select: { + nzBorderless: true + } + }; + // merge local and global config + const mergedConfig = { + ...globalConfig, + ...localConfig + }; + return mergedConfig; + }, + // get global NzConfigService + deps: [[new SkipSelf(), NzConfigService]] + } + ] +}) +``` + ## Dynamically Change Configurations You can alter the global configuration of a specific component through the `set` method of `NzConfigService`. For example: @@ -117,7 +171,6 @@ export class ChangeZorroConfigComponent { constructor(private nzConfigService: NzConfigService) {} onChangeConfig() { - // Grandpa: Oh, I like that! this.nzConfigService.set('button', { nzSize: 'large' }) } } @@ -125,6 +178,7 @@ export class ChangeZorroConfigComponent { All component instances is responsive to this configuration change (as long as they are not configured independently). + ## Priority of Global Configurations For any property that supports global configuration, the sequence of priority is based on following: diff --git a/docs/global-config.zh-CN.md b/docs/global-config.zh-CN.md index fff083a8c0f..18df2862c6f 100644 --- a/docs/global-config.zh-CN.md +++ b/docs/global-config.zh-CN.md @@ -24,7 +24,7 @@ const ngZorroConfig: NzConfig = { CommonModule ], providers: [ - { provide: NZ_CONFIG, useValue: ngZorroConfig } + { provide: NZ_CONFIG, useValue: { ngZorroConfig } } ], bootstrap: [AppComponent] }) @@ -104,9 +104,63 @@ const nzConfigFactory = ( export class AppModule {} ``` -## 动态变更全局配置 -你可以通过调用 `NzConfigService` 的 `set` 方法来改变某个组件的全局配置项,例如: +## 局部生效 + +开发者可以利用 Angular 自带的依赖注入机制,在特定组件内重新设定 `NZ_CONFIG`, 该设定不会影响该组件以外的配置。 + +```typescript +@Component({ + providers: [ + // 重设本地 NzConfigService + NzConfigService, + { + provide: NZ_CONFIG, + useValue: { + button: { + nzSize: 'large' + } + } + } + ] +}) +``` + +也可以使用 `useFactory` 将全局配置与区域配置合并后生效 + +> 注意:全局配置在初始化之后修改将不会影响该部分配置结果 + +```typescript +@Component({ + providers: [ + // 重设本地 NzConfigService + NzConfigService, + { + provide: NZ_CONFIG, + useFactory: (nzConfigService: NzConfigService) => { + const globalConfig = nzConfigService.getConfig(); + const localConfig = { + select: { + nzBorderless: true + } + }; + // 合并全局配置与本地配置 + const mergedConfig = { + ...globalConfig, + ...localConfig + }; + return mergedConfig; + }, + // 获取全局 NzConfigService + deps: [[new SkipSelf(), NzConfigService]] + } + ] +}) +``` + +## 动态变更 + +你可以通过调用 `NzConfigService` 的 `set` 方法来改变某个组件的配置项,例如: ```typescript import { NzConfigService } from 'ng-zorro-antd/core/config'; @@ -118,7 +172,6 @@ export class ChangeZorroConfigComponent { constructor(private nzConfigService: NzConfigService) {} onChangeConfig() { - // 爷爷:我就喜欢大号字! this.nzConfigService.set('button', { nzSize: 'large' }) } } @@ -126,7 +179,7 @@ export class ChangeZorroConfigComponent { 所有的组件实例都会响应这些改变(只要它们没有被单独赋值)。 -## 全局配置项的优先级 +## 优先级说明 对于任何一个属性来说,各个来源的值的优先级如下: @@ -140,6 +193,6 @@ export class ChangeZorroConfigComponent { 最终该 Notification 将会显示 6000 毫秒。 -## 查看所有可用的全局配置项 +## 可配置项 `NzConfig` 接口提供的类型定义信息能够帮助你找到所有支持全局配置项的组件和属性。另外,每个组件的文档都会指出哪些属性可以通过全局配置项的方式指定。 diff --git a/docs/join.zh-CN.md b/docs/join.zh-CN.md index 91dfaf9974d..656bc372695 100644 --- a/docs/join.zh-CN.md +++ b/docs/join.zh-CN.md @@ -5,7 +5,7 @@ title: 加入我们 阿里云实时计算部是阿里巴巴大数据技术体系的核心团队,以 Apache Flink 为核心打造的大数据实时计算平台,我们的技术团队围绕开源技术体系构建,包括来自 Apache Flink / Hadoop / HBase / Kafka / Hive / Zeppelin 等顶级开源项目的十几位 PMC / Committer 成员。 -## 前端开发工程师(P6/P7) +## 高级前端工程师/前端开发专家(P6/P7) #### 工作职责 - 深度参与 Ant Design / NG-ZORRO 等 Github 顶级前端开源项目 @@ -29,5 +29,17 @@ title: 加入我们 - 熟练掌握 CSS3、HTML5、ES6、Webpack 等规范和技术 - 熟悉 Angular / Vue / React 等任意一种前端框架 +## 前端工程师(外包岗位) + +#### 工作职责 +- 深度参与 Ant Design / NG-ZORRO 等 Github 顶级前端开源项目 +- 参与 Apache 顶级项目开发与建设 +- 与国际化团队协作建设实时计算平台(团队一半成员在德国) + +#### 岗位要求 +- 良好规范编码风格 +- 熟练掌握 CSS3、HTML5、ES6、Webpack 等规范和技术 +- 熟悉 Angular / Vue / React 等任意一种前端框架 + 工作地点:杭州
简历投递:yadong.xyd#alibaba-inc.com \ No newline at end of file diff --git a/package.json b/package.json index 221120e07ce..20fc960c381 100644 --- a/package.json +++ b/package.json @@ -135,7 +135,6 @@ "terser": "^5.5.1", "ts-node": "~9.1.1", "tslib": "^2.0.3", - "tslint": "~6.1.3", "typescript": "~4.2.4", "yaml-front-matter": "^4.1.1", "zone.js": "~0.11.4" diff --git a/scripts/site/generate-site.js b/scripts/site/generate-site.js index aa68719daa8..1f2f59e4892 100644 --- a/scripts/site/generate-site.js +++ b/scripts/site/generate-site.js @@ -17,7 +17,7 @@ const arg = process.argv[2]; const showCasePath = path.resolve(__dirname, '../../site'); function generate(target) { - const isSyncSpecific = target && (target !== 'init'); + const isSyncSpecific = target && target !== 'init'; if (!target) { fs.removeSync(`${showCasePath}/doc`); fs.copySync(path.resolve(__dirname, '_site/doc'), `${showCasePath}/doc`); @@ -29,7 +29,7 @@ function generate(target) { } const showCaseTargetPath = `${showCasePath}/doc/app/`; const iframeTargetPath = `${showCasePath}/iframe/app/`; -// read components folder + // read components folder const rootPath = path.resolve(__dirname, '../../components'); const rootDir = fs.readdirSync(rootPath); const componentsDocMap = {}; @@ -41,7 +41,7 @@ function generate(target) { } } const componentDirPath = path.join(rootPath, componentName); - const skips = ['style', 'core', 'locale', 'i18n', 'version', 'experimental'] + const skips = ['style', 'core', 'locale', 'cdk', 'i18n', 'version', 'experimental']; if (skips.indexOf(componentName) !== -1) { return; } @@ -56,27 +56,42 @@ function generate(target) { if (fs.existsSync(demoDirPath)) { const demoDir = fs.readdirSync(demoDirPath); demoDir.forEach(demo => { - - if (/.md$/.test(demo)) { - const nameKey = nameWithoutSuffixUtil(demo); - const demoMarkDownFile = fs.readFileSync(path.join(demoDirPath, demo)); - demoMap[nameKey] = parseDemoMdUtil(demoMarkDownFile); - demoMap[nameKey]['name'] = `NzDemo${camelCase(capitalizeFirstLetter(componentName))}${camelCase(capitalizeFirstLetter(nameKey))}Component`; - demoMap[nameKey]['enCode'] = generateCodeBox(componentName, demoMap[nameKey]['name'], nameKey, demoMap[nameKey].meta.title['en-US'], demoMap[nameKey].en, demoMap[nameKey].meta.iframe); - demoMap[nameKey]['zhCode'] = generateCodeBox(componentName, demoMap[nameKey]['name'], nameKey, demoMap[nameKey].meta.title['zh-CN'], demoMap[nameKey].zh, demoMap[nameKey].meta.iframe); - } - if (/.ts$/.test(demo)) { - const nameKey = nameWithoutSuffixUtil(demo); - demoMap[nameKey].ts = String(fs.readFileSync(path.join(demoDirPath, demo))); - // copy ts file to site->${component} folder - fs.writeFileSync(path.join(showCaseComponentPath, demo), demoMap[nameKey].ts); - } - if (demo === 'module') { - const data = String(fs.readFileSync(path.join(demoDirPath, demo))); - fs.writeFileSync(path.join(showCaseComponentPath, 'module.ts'), data); - } - }); - } + if (/.md$/.test(demo)) { + const nameKey = nameWithoutSuffixUtil(demo); + const demoMarkDownFile = fs.readFileSync(path.join(demoDirPath, demo)); + demoMap[nameKey] = parseDemoMdUtil(demoMarkDownFile); + demoMap[nameKey]['name'] = `NzDemo${camelCase(capitalizeFirstLetter(componentName))}${camelCase( + capitalizeFirstLetter(nameKey) + )}Component`; + demoMap[nameKey]['enCode'] = generateCodeBox( + componentName, + demoMap[nameKey]['name'], + nameKey, + demoMap[nameKey].meta.title['en-US'], + demoMap[nameKey].en, + demoMap[nameKey].meta.iframe + ); + demoMap[nameKey]['zhCode'] = generateCodeBox( + componentName, + demoMap[nameKey]['name'], + nameKey, + demoMap[nameKey].meta.title['zh-CN'], + demoMap[nameKey].zh, + demoMap[nameKey].meta.iframe + ); + } + if (/.ts$/.test(demo)) { + const nameKey = nameWithoutSuffixUtil(demo); + demoMap[nameKey].ts = String(fs.readFileSync(path.join(demoDirPath, demo))); + // copy ts file to site->${component} folder + fs.writeFileSync(path.join(showCaseComponentPath, demo), demoMap[nameKey].ts); + } + if (demo === 'module') { + const data = String(fs.readFileSync(path.join(demoDirPath, demo))); + fs.writeFileSync(path.join(showCaseComponentPath, 'module.ts'), data); + } + }); + } // handle components->${component}->page folder, parent component of demo page let pageDemo = ''; @@ -101,22 +116,28 @@ function generate(target) { pageDemo.zhCode = pageDemo.raw.replace(/locale;/g, zhLocale); } - // handle components->${component}->doc folder - const result = { - name: componentName, - docZh: parseDocMdUtil(fs.readFileSync(path.join(componentDirPath, 'doc/index.zh-CN.md')), `components/${componentName}/doc/index.zh-CN.md`), - docEn: parseDocMdUtil(fs.readFileSync(path.join(componentDirPath, 'doc/index.en-US.md')), `components/${componentName}/doc/index.en-US.md`), - demoMap, - pageDemo - }; - componentsDocMap[componentName] = { zh: result.docZh.meta, en: result.docEn.meta }; - componentsMap[componentName] = demoMap; - generateDemo(showCaseComponentPath, result); - generateDemoCodeFiles(result, showCasePath) + // handle components->${component}->doc folder + const result = { + name: componentName, + docZh: parseDocMdUtil( + fs.readFileSync(path.join(componentDirPath, 'doc/index.zh-CN.md')), + `components/${componentName}/doc/index.zh-CN.md` + ), + docEn: parseDocMdUtil( + fs.readFileSync(path.join(componentDirPath, 'doc/index.en-US.md')), + `components/${componentName}/doc/index.en-US.md` + ), + demoMap, + pageDemo + }; + componentsDocMap[componentName] = { zh: result.docZh.meta, en: result.docEn.meta }; + componentsMap[componentName] = demoMap; + generateDemo(showCaseComponentPath, result); + generateDemoCodeFiles(result, showCasePath); } }); -// handle iframe folder + // handle iframe folder generateIframe(iframeTargetPath, componentsMap); if (!isSyncSpecific) { @@ -146,4 +167,4 @@ if (require.main === module) { generate(arg); } -module.exports = generate; \ No newline at end of file +module.exports = generate;