Skip to content

Commit

Permalink
refactor: migrate to standard decorators (#8739)
Browse files Browse the repository at this point in the history
  • Loading branch information
HyperLife1119 authored Nov 21, 2024
1 parent 5779804 commit c79c203
Show file tree
Hide file tree
Showing 23 changed files with 127 additions and 101 deletions.
4 changes: 2 additions & 2 deletions components/affix/affix.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ export class NzAffixComponent implements AfterViewInit, OnChanges, OnDestroy, On
@Input() nzTarget?: string | Element | Window;

@Input({ transform: numberAttributeWithZeroFallback })
@WithConfig<number | null>()
@WithConfig()
nzOffsetTop?: null | number;

@Input({ transform: numberAttributeWithZeroFallback })
@WithConfig<number | null>()
@WithConfig()
nzOffsetBottom?: null | number;

@Output() readonly nzChange = new EventEmitter<boolean>();
Expand Down
4 changes: 2 additions & 2 deletions components/anchor/anchor.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@ export class NzAnchorComponent implements OnDestroy, AfterViewInit, OnChanges {
nzBounds: number = 5;

@Input({ transform: numberAttributeWithZeroFallback })
@WithConfig<number>()
@WithConfig()
nzOffsetTop?: number = undefined;

@Input({ transform: numberAttributeWithZeroFallback })
@WithConfig<number>()
@WithConfig()
nzTargetOffset?: number = undefined;

@Input() nzContainer?: string | HTMLElement;
Expand Down
5 changes: 3 additions & 2 deletions components/breadcrumb/breadcrumb.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
Renderer2,
TemplateRef,
ViewEncapsulation,
booleanAttribute
booleanAttribute,
forwardRef
} from '@angular/core';
import { ActivatedRoute, NavigationEnd, PRIMARY_OUTLET, Params, Router } from '@angular/router';
import { Subject } from 'rxjs';
Expand All @@ -39,7 +40,7 @@ export interface BreadcrumbOption {
selector: 'nz-breadcrumb',
exportAs: 'nzBreadcrumb',
preserveWhitespaces: false,
providers: [{ provide: NzBreadcrumb, useExisting: NzBreadCrumbComponent }],
providers: [{ provide: NzBreadcrumb, useExisting: forwardRef(() => NzBreadCrumbComponent) }],
standalone: true,
imports: [NzBreadCrumbItemComponent],
template: `
Expand Down
88 changes: 44 additions & 44 deletions components/core/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { CSP_NONCE, Injectable, inject } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { filter, mapTo } from 'rxjs/operators';
import { filter, map } from 'rxjs/operators';

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

Expand Down Expand Up @@ -47,7 +47,7 @@ export class NzConfigService {
getConfigChangeEventForComponent(componentName: NzConfigKey): Observable<void> {
return this.configUpdated$.pipe(
filter(n => n === componentName),
mapTo(undefined)
map(() => undefined)
);
}

Expand All @@ -60,51 +60,51 @@ export class NzConfigService {
}
}

/* eslint-disable no-invalid-this */

/**
* This decorator is used to decorate properties. If a property is decorated, it would try to load default value from
* config.
* This decorator is used to decorate class field. If a class field is decorated and unassigned, it would try to load default value from `NZ_CONFIG`
*
* @note that the class must have `_nzModuleName`({@link NzConfigKey}) property.
* @example
* ```ts
* class ExampleComponent {
* private readonly _nzModuleName: NzConfigKey = 'button';
* @WithConfig() size: string = 'default';
* }
* ```
*/
// eslint-disable-next-line
export function WithConfig<T>() {
return function ConfigDecorator(
target: NzSafeAny,
propName: NzSafeAny,
originalDescriptor?: TypedPropertyDescriptor<T>
): NzSafeAny {
const privatePropName = `$$__zorroConfigDecorator__${propName}`;

Object.defineProperty(target, privatePropName, {
configurable: true,
writable: true,
enumerable: false
});
export function WithConfig<This, Value>() {
return function (_value: undefined, context: ClassFieldDecoratorContext<This, Value>) {
context.addInitializer(function () {
const nzConfigService = inject(NzConfigService);
const originalValue = this[context.name as keyof This];

let value: Value;
let assignedByUser = false;

Object.defineProperty(this, context.name, {
get: () => {
const configValue = nzConfigService.getConfigForComponent(
this['_nzModuleName' as keyof This] as NzConfigKey
)?.[context.name as keyof NzConfig[NzConfigKey]];

if (assignedByUser) {
return value;
}

if (isDefined(configValue)) {
return configValue;
}

return {
get(): T | undefined {
const originalValue = originalDescriptor?.get ? originalDescriptor.get.bind(this)() : this[privatePropName];
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;
}
},
set(value?: T): void {
// If the value is assigned, we consider the newly assigned value as 'assigned by user'.
this.propertyAssignCounter = this.propertyAssignCounter || {};
this.propertyAssignCounter[propName] = (this.propertyAssignCounter[propName] || 0) + 1;

if (originalDescriptor?.set) {
originalDescriptor.set.bind(this)(value!);
} else {
this[privatePropName] = value;
}
},
configurable: true,
enumerable: true
};
},
set: (newValue: Value) => {
// if the newValue is undefined, we also consider it as not assigned by user
assignedByUser = isDefined(newValue);
value = newValue;
},
enumerable: true,
configurable: true
});
});
};
}
2 changes: 1 addition & 1 deletion components/dropdown/dropdown.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class NzDropDownDirective implements AfterViewInit, OnDestroy, OnChanges
@Input() nzDropdownMenu: NzDropdownMenuComponent | null = null;
@Input() nzTrigger: 'click' | 'hover' = 'hover';
@Input() nzMatchWidthElement: ElementRef | null = null;
@Input({ transform: booleanAttribute }) @WithConfig<boolean>() nzBackdrop = false;
@Input({ transform: booleanAttribute }) @WithConfig() nzBackdrop = false;
@Input({ transform: booleanAttribute }) nzClickHide = true;
@Input({ transform: booleanAttribute }) nzDisabled = false;
@Input({ transform: booleanAttribute }) nzVisible = false;
Expand Down
18 changes: 7 additions & 11 deletions components/float-button/float-button-top.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import {
Component,
ElementRef,
EventEmitter,
Inject,
inject,
Input,
NgZone,
numberAttribute,
OnChanges,
OnDestroy,
OnInit,
Optional,
Output,
SimpleChanges,
TemplateRef,
Expand All @@ -31,8 +31,6 @@ import { debounceTime, takeUntil } from 'rxjs/operators';
import { fadeMotion } from 'ng-zorro-antd/core/animation';
import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config';
import { NzDestroyService, NzScrollService } from 'ng-zorro-antd/core/services';
import { NumberInput, NzSafeAny } from 'ng-zorro-antd/core/types';
import { InputNumber } from 'ng-zorro-antd/core/util';
import { NzIconModule } from 'ng-zorro-antd/icon';

import { NzFloatButtonComponent } from './float-button.component';
Expand Down Expand Up @@ -75,11 +73,9 @@ const passiveEventListenerOptions = normalizePassiveListenerOptions({ passive: t
})
export class NzFloatButtonTopComponent implements OnInit, OnDestroy, OnChanges {
readonly _nzModuleName: NzConfigKey = NZ_CONFIG_MODULE_NAME;
static ngAcceptInputType_nzVisibilityHeight: NumberInput;
static ngAcceptInputType_nzDuration: NumberInput;

private scrollListenerDestroy$ = new Subject<void>();
private target: HTMLElement | null = null;
private target?: HTMLElement | null = null;

visible: boolean = false;
dir: Direction = 'ltr';
Expand All @@ -91,9 +87,9 @@ export class NzFloatButtonTopComponent implements OnInit, OnDestroy, OnChanges {
@Input() nzDescription: TemplateRef<void> | null = null;

@Input() nzTemplate?: TemplateRef<void>;
@Input() @WithConfig() @InputNumber() nzVisibilityHeight: number = 400;
@Input({ transform: numberAttribute }) @WithConfig() nzVisibilityHeight: number = 400;
@Input() nzTarget?: string | HTMLElement;
@Input() @InputNumber() nzDuration: number = 450;
@Input({ transform: numberAttribute }) nzDuration: number = 450;
@Output() readonly nzOnClick: EventEmitter<boolean> = new EventEmitter();

@ViewChild('backTop', { static: false })
Expand All @@ -114,18 +110,18 @@ export class NzFloatButtonTopComponent implements OnInit, OnDestroy, OnChanges {
}
}

private doc = inject(DOCUMENT);
private backTopClickSubscription = Subscription.EMPTY;

constructor(
@Inject(DOCUMENT) private doc: NzSafeAny,
public nzConfigService: NzConfigService,
private scrollSrv: NzScrollService,
private platform: Platform,
private cd: ChangeDetectorRef,
private zone: NgZone,
private cdr: ChangeDetectorRef,
private destroy$: NzDestroyService,
@Optional() private directionality: Directionality
private directionality: Directionality
) {
this.dir = this.directionality.value;
}
Expand Down
3 changes: 2 additions & 1 deletion components/graph/graph.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
ViewChildren,
ViewEncapsulation,
booleanAttribute,
forwardRef,
inject
} from '@angular/core';
import { Observable, ReplaySubject, Subject, Subscription, forkJoin } from 'rxjs';
Expand Down Expand Up @@ -72,7 +73,7 @@ export function isDataSource(value: NzSafeAny): value is NzGraphData {
encapsulation: ViewEncapsulation.None,
selector: 'nz-graph',
exportAs: 'nzGraph',
providers: [{ provide: NzGraph, useExisting: NzGraphComponent }],
providers: [{ provide: NzGraph, useExisting: forwardRef(() => NzGraphComponent) }],
template: `
<ng-content></ng-content>
<svg width="100%" height="100%">
Expand Down
6 changes: 3 additions & 3 deletions components/image/image-preview.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
Component,
ElementRef,
EventEmitter,
Inject,
inject,
NgZone,
OnInit,
ViewChild,
Expand Down Expand Up @@ -230,6 +230,7 @@ export class NzImagePreviewComponent implements OnInit {
@ViewChild('imgRef') imageRef!: ElementRef<HTMLImageElement>;
@ViewChild('imagePreviewWrapper', { static: true }) imagePreviewWrapper!: ElementRef<HTMLElement>;

private document = inject(DOCUMENT);
private zoom: number;
private rotate: number;
private scaleStep: number;
Expand All @@ -251,8 +252,7 @@ export class NzImagePreviewComponent implements OnInit {
public nzConfigService: NzConfigService,
public config: NzImagePreviewOptions,
private destroy$: NzDestroyService,
private sanitizer: DomSanitizer,
@Inject(DOCUMENT) private document: Document
private sanitizer: DomSanitizer
) {
this.zoom = this.config.nzZoom ?? this._defaultNzZoom;
this.scaleStep = this.config.nzScaleStep ?? this._defaultNzScaleStep;
Expand Down
8 changes: 4 additions & 4 deletions components/select/select.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterCon
@Input() nzId: string | null = null;
@Input() nzSize: NzSelectSizeType = 'default';
@Input() nzStatus: NzStatus = '';
@Input() @WithConfig<number>() nzOptionHeightPx = 32;
@Input() @WithConfig() nzOptionHeightPx = 32;
@Input() nzOptionOverflowSize = 8;
@Input() nzDropdownClassName: string[] | string | null = null;
@Input() nzDropdownMatchSelectWidth = true;
Expand All @@ -236,7 +236,7 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterCon
@Input() nzDropdownRender: TemplateRef<NzSafeAny> | null = null;
@Input() nzCustomTemplate: TemplateRef<{ $implicit: NzSelectItemInterface }> | null = null;
@Input()
@WithConfig<TemplateRef<NzSafeAny> | string | null>()
@WithConfig()
nzSuffixIcon: TemplateRef<NzSafeAny> | string | null = null;
@Input() nzClearIcon: TemplateRef<NzSafeAny> | null = null;
@Input() nzRemoveIcon: TemplateRef<NzSafeAny> | null = null;
Expand All @@ -248,7 +248,7 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterCon
@Input() nzFilterOption: NzFilterOptionType = defaultFilterOption;
@Input() compareWith: (o1: NzSafeAny, o2: NzSafeAny) => boolean = (o1: NzSafeAny, o2: NzSafeAny) => o1 === o2;
@Input({ transform: booleanAttribute }) nzAllowClear = false;
@Input({ transform: booleanAttribute }) @WithConfig<boolean>() nzBorderless = false;
@Input({ transform: booleanAttribute }) @WithConfig() nzBorderless = false;
@Input({ transform: booleanAttribute }) nzShowSearch = false;
@Input({ transform: booleanAttribute }) nzLoading = false;
@Input({ transform: booleanAttribute }) nzAutoFocus = false;
Expand All @@ -257,7 +257,7 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterCon
@Input({ transform: booleanAttribute }) nzDisabled = false;
@Input({ transform: booleanAttribute }) nzOpen = false;
@Input({ transform: booleanAttribute }) nzSelectOnTab = false;
@Input({ transform: booleanAttribute }) @WithConfig<boolean>() nzBackdrop = false;
@Input({ transform: booleanAttribute }) @WithConfig() nzBackdrop = false;
@Input() nzOptions: NzSelectOptionInterface[] = [];

@Input({ transform: booleanAttribute })
Expand Down
2 changes: 1 addition & 1 deletion components/table/src/addon/filter-trigger.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class NzFilterTriggerComponent implements OnInit {
@Input() nzDropdownMenu!: NzDropdownMenuComponent;
@Input() nzVisible = false;

@Input({ transform: booleanAttribute }) @WithConfig<boolean>() nzBackdrop = false;
@Input({ transform: booleanAttribute }) @WithConfig() nzBackdrop = false;

@Output() readonly nzVisibleChange = new EventEmitter<boolean>();

Expand Down
3 changes: 2 additions & 1 deletion components/tabs/tabset.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
Component,
ContentChildren,
EventEmitter,
forwardRef,
inject,
Input,
NgZone,
Expand Down Expand Up @@ -67,7 +68,7 @@ let nextId = 0;
providers: [
{
provide: NZ_TAB_SET,
useExisting: NzTabSetComponent
useExisting: forwardRef(() => NzTabSetComponent)
}
],
template: `
Expand Down
3 changes: 2 additions & 1 deletion components/time-picker/time-picker-panel.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
ViewChild,
ViewEncapsulation,
booleanAttribute,
forwardRef,
numberAttribute
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
Expand Down Expand Up @@ -146,7 +147,7 @@ export type NzTimePickerUnit = 'hour' | 'minute' | 'second' | '12-hour';
'[class.ant-picker-time-panel-narrow]': `enabledColumns < 3`,
'[class.ant-picker-time-panel-placement-bottomLeft]': `!nzInDatePicker`
},
providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: NzTimePickerPanelComponent, multi: true }],
providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NzTimePickerPanelComponent), multi: true }],
imports: [DecimalPipe, NgTemplateOutlet, NzI18nModule, NzButtonModule],
standalone: true
})
Expand Down
3 changes: 2 additions & 1 deletion components/time-picker/time-picker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
ViewChild,
ViewEncapsulation,
booleanAttribute,
forwardRef,
inject
} from '@angular/core';
import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
Expand Down Expand Up @@ -144,7 +145,7 @@ const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'timePicker';
'(click)': 'open()'
},
animations: [slideMotion],
providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: NzTimePickerComponent, multi: true }],
providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NzTimePickerComponent), multi: true }],
imports: [
AsyncPipe,
FormsModule,
Expand Down
Loading

0 comments on commit c79c203

Please sign in to comment.