From 3fcec916b81a284fc8934846aab26d5b8ce99a1b Mon Sep 17 00:00:00 2001 From: Laffery <49607541+Laffery@users.noreply.github.com> Date: Fri, 17 Jan 2025 14:37:57 +0800 Subject: [PATCH] feat(module:popover,popconfirm,tooltip): overlayClassName supports space delimited classes string (#8972) --- components/popconfirm/popconfirm.spec.ts | 25 +++++++++++++++++ components/popover/popover.spec.ts | 35 ++++++++++++++++++++++-- components/tooltip/base.ts | 12 +++++++- components/tooltip/tooltip.spec.ts | 14 +++++++++- components/tooltip/tooltip.ts | 2 +- 5 files changed, 83 insertions(+), 5 deletions(-) diff --git a/components/popconfirm/popconfirm.spec.ts b/components/popconfirm/popconfirm.spec.ts index 90c6277a9bf..57afb1d500b 100644 --- a/components/popconfirm/popconfirm.spec.ts +++ b/components/popconfirm/popconfirm.spec.ts @@ -241,6 +241,29 @@ describe('NzPopconfirm', () => { fixture.detectChanges(); expect(overlayContainerElement.children[0].classList).toContain('cdk-overlay-backdrop'); })); + + it('should change overlayClass when the nzPopconfirmOverlayClassName is changed', fakeAsync(() => { + const triggerElement = component.stringTemplate.nativeElement; + + dispatchMouseEvent(triggerElement, 'click'); + waitingForTooltipToggling(); + + component.class = 'testClass2'; + fixture.detectChanges(); + + expect(overlayContainerElement.querySelector('.testClass')).toBeNull(); + expect(overlayContainerElement.querySelector('.testClass2')).not.toBeNull(); + })); + + it('should nzPopconfirmOverlayClassName support classes listed in the string (space delimited)', fakeAsync(() => { + const triggerElement = component.stringTemplate.nativeElement; + component.class = 'testClass1 testClass2'; + + dispatchMouseEvent(triggerElement, 'click'); + waitingForTooltipToggling(); + + expect(overlayContainerElement.querySelector('.testClass1.testClass2')).not.toBeNull(); + })); }); @Component({ @@ -259,6 +282,7 @@ describe('NzPopconfirm', () => { [nzBeforeConfirm]="beforeConfirm" [nzPopconfirmShowArrow]="nzPopconfirmShowArrow" [nzPopconfirmBackdrop]="nzPopconfirmBackdrop" + [nzPopconfirmOverlayClassName]="class" (nzOnConfirm)="confirm()" (nzOnCancel)="cancel()" > @@ -297,4 +321,5 @@ export class NzPopconfirmTestNewComponent { @ViewChild('iconTemplate', { static: false }) iconTemplate!: ElementRef; visible = false; + class = 'testClass'; } diff --git a/components/popover/popover.spec.ts b/components/popover/popover.spec.ts index ce6f8816b47..8250074c611 100644 --- a/components/popover/popover.spec.ts +++ b/components/popover/popover.spec.ts @@ -105,7 +105,7 @@ describe('NzPopover', () => { expect(overlayContainerElement.children[0].classList).toContain('cdk-overlay-backdrop'); })); - it('nzPopoverOverlayClickable: false is to prohibit hiding', fakeAsync(() => { + it('should prohibit hiding popover when nzPopoverOverlayClickable is false', fakeAsync(() => { const triggerElement = component.hideTemplate.nativeElement; dispatchMouseEvent(triggerElement, 'click'); @@ -116,12 +116,42 @@ describe('NzPopover', () => { waitingForTooltipToggling(); expect(overlayContainerElement.textContent).toContain('content-string'); })); + + it('should change overlayClass when the nzPopoverOverlayClassName is changed', fakeAsync(() => { + const triggerElement = component.stringPopover.nativeElement; + + dispatchMouseEvent(triggerElement, 'mouseenter'); + waitingForTooltipToggling(); + + component.class = 'testClass2'; + fixture.detectChanges(); + + expect(overlayContainerElement.querySelector('.testClass')).toBeNull(); + expect(overlayContainerElement.querySelector('.testClass2')).not.toBeNull(); + })); + + it('should nzPopoverOverlayClassName support classes listed in the string (space delimited)', fakeAsync(() => { + const triggerElement = component.stringPopover.nativeElement; + component.class = 'testClass1 testClass2'; + + dispatchMouseEvent(triggerElement, 'mouseenter'); + waitingForTooltipToggling(); + + expect(overlayContainerElement.querySelector('.testClass1.testClass2')).not.toBeNull(); + })); }); @Component({ imports: [NzPopoverModule], template: ` - Show + Show Show @@ -172,4 +202,5 @@ export class NzPopoverTestComponent { content = 'content'; visible = false; + class = 'testClass'; } diff --git a/components/tooltip/base.ts b/components/tooltip/base.ts index 8a7e7edbd30..aa39b3d9daf 100644 --- a/components/tooltip/base.ts +++ b/components/tooltip/base.ts @@ -494,11 +494,21 @@ export abstract class NzTooltipBaseComponent implements OnDestroy, OnInit { protected updateStyles(): void { this._classMap = { - [this.nzOverlayClassName]: true, + ...this.transformClassListToMap(this.nzOverlayClassName), [`${this._prefix}-placement-${this.preferredPlacement}`]: true }; } + protected transformClassListToMap(klass: string): Record { + const result: Record = {}; + /** + * @see https://github.com/angular/angular/blob/f6e97763cfab9fa2bea6e6b1303b64f1b499c3ef/packages/common/src/directives/ng_class.ts#L92 + */ + const classes = klass !== null ? klass.split(/\s+/) : []; + classes.forEach(className => (result[className] = true)); + return result; + } + /** * Empty component cannot be opened. */ diff --git a/components/tooltip/tooltip.spec.ts b/components/tooltip/tooltip.spec.ts index a28285ddc3a..52f1d7dd67b 100644 --- a/components/tooltip/tooltip.spec.ts +++ b/components/tooltip/tooltip.spec.ts @@ -203,7 +203,7 @@ describe('nz-tooltip', () => { expect(overlayContainerElement.querySelector('.ant-tooltip')!.style.color).toBe('rgb(0, 0, 0)'); })); - it('should change overlayClass when the overlayClass is changed', fakeAsync(() => { + it('should change overlayClass when the nzTooltipOverlayClassName is changed', fakeAsync(() => { const triggerElement = component.titleString.nativeElement; dispatchMouseEvent(triggerElement, 'mouseenter'); @@ -212,9 +212,21 @@ describe('nz-tooltip', () => { component.class = 'testClass2'; fixture.detectChanges(); + expect(overlayContainerElement.querySelector('.testClass')).toBeNull(); expect(overlayContainerElement.querySelector('.testClass2')).not.toBeNull(); })); + it('should nzTooltipOverlayClassName support classes listed in the string (space delimited)', fakeAsync(() => { + const triggerElement = component.titleString.nativeElement; + component.class = 'testClass1 testClass2'; + fixture.detectChanges(); + + dispatchMouseEvent(triggerElement, 'mouseenter'); + waitingForTooltipToggling(); + + expect(overlayContainerElement.querySelector('.testClass1.testClass2')).not.toBeNull(); + })); + it('should hide when the title is changed to null', fakeAsync(() => { const title = 'title-string'; const triggerElement = component.titleString.nativeElement; diff --git a/components/tooltip/tooltip.ts b/components/tooltip/tooltip.ts index bf9dfa14ed0..e8d7db8b49e 100644 --- a/components/tooltip/tooltip.ts +++ b/components/tooltip/tooltip.ts @@ -133,7 +133,7 @@ export class NzToolTipComponent extends NzTooltipBaseComponent { const isColorPreset = this.nzColor && isPresetColor(this.nzColor); this._classMap = { - [this.nzOverlayClassName]: true, + ...this.transformClassListToMap(this.nzOverlayClassName), [`${this._prefix}-placement-${this.preferredPlacement}`]: true, [`${this._prefix}-${this.nzColor}`]: isColorPreset };