From 7c79ab37a8c0b4bc47bf1873c167417f316c94a9 Mon Sep 17 00:00:00 2001 From: Egor Volvachev <34657605+volvachev@users.noreply.github.com> Date: Sat, 18 Nov 2023 16:30:41 +0300 Subject: [PATCH] feat(module:slider): add the ability to use a template (#7505) --- components/slider/demo/tip-formatter.ts | 4 ++ components/slider/doc/index.en-US.md | 2 +- components/slider/doc/index.zh-CN.md | 2 +- components/slider/handle.component.ts | 15 +++++-- components/slider/slider.component.ts | 3 +- components/slider/slider.spec.ts | 53 +++++++++++++++++++++++++ components/tooltip/tooltip.ts | 2 +- 7 files changed, 73 insertions(+), 8 deletions(-) diff --git a/components/slider/demo/tip-formatter.ts b/components/slider/demo/tip-formatter.ts index 918b2e114f..0450b67fbd 100644 --- a/components/slider/demo/tip-formatter.ts +++ b/components/slider/demo/tip-formatter.ts @@ -5,6 +5,10 @@ import { Component } from '@angular/core'; template: ` + + + Slider value: {{ value }} + ` }) export class NzDemoSliderTipFormatterComponent { diff --git a/components/slider/doc/index.en-US.md b/components/slider/doc/index.en-US.md index bfca55f21b..9e3ae17228 100644 --- a/components/slider/doc/index.en-US.md +++ b/components/slider/doc/index.en-US.md @@ -29,7 +29,7 @@ import { NzSliderModule } from 'ng-zorro-antd/slider'; | `[nzMin]` | The minimum value the slider can slide to. | `number` | `0` | | `[nzRange]` | dual thumb mode | `boolean` | `false` | | `[nzStep]` | The granularity the slider can step through values. Must greater than 0, and be divided by (max - min) . When `marks` no null, `step` can be `null`. | `number \| null` | `1` | -| `[nzTipFormatter]` | Slider will pass its value to `tipFormatter`, and display its value in Tooltip, and hide Tooltip when return value is null. | `(value: number) => string` | - | +| `[nzTipFormatter]` | Slider will pass its value to `tipFormatter`, and display its value in Tooltip, and hide Tooltip when return value is null. | `(value: number) => string \| TemplateRef` | - | | `[ngModel]` | The value of slider. When `range` is `false`, use `number`, otherwise, use `[number, number]` | `number \| number[]` | - | | `[nzVertical]` | If true, the slider will be vertical. | `boolean` | `false` | | `[nzReverse]` | Reverse the component | `boolean` | `false` | diff --git a/components/slider/doc/index.zh-CN.md b/components/slider/doc/index.zh-CN.md index 9d0d122845..0ad460a21b 100644 --- a/components/slider/doc/index.zh-CN.md +++ b/components/slider/doc/index.zh-CN.md @@ -30,7 +30,7 @@ import { NzSliderModule } from 'ng-zorro-antd/slider'; | `[nzMin]` | 最小值 | `number` | `0` | | `[nzRange]` | 双滑块模式 | `boolean` | `false` | | `[nzStep]` | 步长,取值必须大于 0,并且可被 (max - min) 整除。当 `marks` 不为空对象时,可以设置 `step` 为 `null`,此时 Slider 的可选值仅有 marks 标出来的部分。 | `number \| null` | `1` | -| `[nzTipFormatter]` | Slider 会把当前值传给 `nzTipFormatter`,并在 Tooltip 中显示 `nzTipFormatter` 的返回值,若为 null,则隐藏 Tooltip。 | `(value: number) => string` | - | +| `[nzTipFormatter]` | Slider 会把当前值传给 `nzTipFormatter`,并在 Tooltip 中显示 `nzTipFormatter` 的返回值,若为 null,则隐藏 Tooltip。 | `(value: number) => string \| TemplateRef` | - | | `[ngModel]` | 设置当前取值。当 `range` 为 `false` 时,使用 `number`,否则用 `[number, number]` | `number \| number[]` | - | | `[nzVertical]` | 值为 `true` 时,Slider 为垂直方向 | `boolean` | `false` | | `[nzReverse]` | 反向坐标轴 | `boolean` | `false` | diff --git a/components/slider/handle.component.ts b/components/slider/handle.component.ts index b4f3fe40c9..e92573a0b1 100644 --- a/components/slider/handle.component.ts +++ b/components/slider/handle.component.ts @@ -12,11 +12,12 @@ import { Input, OnChanges, SimpleChanges, + TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core'; -import { BooleanInput, NgStyleInterface } from 'ng-zorro-antd/core/types'; +import { BooleanInput, NgStyleInterface, NzTSType } from 'ng-zorro-antd/core/types'; import { InputBoolean } from 'ng-zorro-antd/core/util'; import { NzTooltipDirective } from 'ng-zorro-antd/tooltip'; @@ -37,6 +38,7 @@ import { NzSliderShowTooltip } from './typings'; nz-tooltip [ngStyle]="style" [nzTooltipTitle]="tooltipFormatter === null || tooltipVisible === 'never' ? null : tooltipTitle" + [nzTooltipTitleContext]="{ $implicit: value }" [nzTooltipTrigger]="null" [nzTooltipPlacement]="tooltipPlacement" > @@ -58,11 +60,11 @@ export class NzSliderHandleComponent implements OnChanges { @Input() value?: number; @Input() tooltipVisible: NzSliderShowTooltip = 'default'; @Input() tooltipPlacement?: string; - @Input() tooltipFormatter?: null | ((value: number) => string); + @Input() tooltipFormatter?: null | ((value: number) => string) | TemplateRef; @Input() @InputBoolean() active = false; @Input() dir: Direction = 'ltr'; - tooltipTitle?: string; + tooltipTitle?: NzTSType; style: NgStyleInterface = {}; constructor(private sliderService: NzSliderService, private cdr: ChangeDetectorRef) {} @@ -124,7 +126,12 @@ export class NzSliderHandleComponent implements OnChanges { } private updateTooltipTitle(): void { - this.tooltipTitle = this.tooltipFormatter ? this.tooltipFormatter(this.value!) : `${this.value}`; + if (this.tooltipFormatter) { + this.tooltipTitle = + typeof this.tooltipFormatter === 'function' ? this.tooltipFormatter(this.value!) : this.tooltipFormatter; + } else { + this.tooltipTitle = `${this.value}`; + } } private updateTooltipPosition(): void { diff --git a/components/slider/slider.component.ts b/components/slider/slider.component.ts index 0b99505290..776f466be0 100644 --- a/components/slider/slider.component.ts +++ b/components/slider/slider.component.ts @@ -20,6 +20,7 @@ import { Output, QueryList, SimpleChanges, + TemplateRef, ViewChild, ViewChildren, ViewEncapsulation, @@ -147,7 +148,7 @@ export class NzSliderComponent implements ControlValueAccessor, OnInit, OnChange @Input() @InputNumber() nzStep = 1; @Input() nzTooltipVisible: NzSliderShowTooltip = 'default'; @Input() nzTooltipPlacement: string = 'top'; - @Input() nzTipFormatter?: null | ((value: number) => string); + @Input() nzTipFormatter?: null | ((value: number) => string) | TemplateRef; @Output() readonly nzOnAfterChange = new EventEmitter(); diff --git a/components/slider/slider.spec.ts b/components/slider/slider.spec.ts index ad55831041..c1ae7dc231 100644 --- a/components/slider/slider.spec.ts +++ b/components/slider/slider.spec.ts @@ -221,6 +221,46 @@ describe('nz-slider', () => { })); }); + describe('show template tooltip', () => { + let testBed: ComponentBed; + let fixture: ComponentFixture; + let testComponent: SliderShowTemplateTooltipComponent; + + beforeEach(() => { + testBed = createComponentBed(SliderShowTemplateTooltipComponent, { + imports: [NzSliderModule, FormsModule, ReactiveFormsModule, NoopAnimationsModule] + }); + fixture = testBed.fixture; + fixture.detectChanges(); + testComponent = fixture.debugElement.componentInstance; + sliderDebugElement = fixture.debugElement.query(By.directive(NzSliderComponent)); + sliderInstance = sliderDebugElement.injector.get(NzSliderComponent); + sliderNativeElement = sliderInstance.slider.nativeElement; + }); + + beforeEach(inject([OverlayContainer], (oc: OverlayContainer) => { + overlayContainerElement = oc.getContainerElement(); + })); + + it('should preview template tooltip', fakeAsync(() => { + testComponent.show = 'always'; + fixture.detectChanges(); + tick(400); + fixture.detectChanges(); + expect(overlayContainerElement.textContent).toContain('Slider value: 0'); + + dispatchClickEventSequence(sliderNativeElement, 0.13); + fixture.detectChanges(); + expect(overlayContainerElement.textContent).toContain('Slider value: 13'); + + // Always show tooltip even when handle is not hovered. + fixture.detectChanges(); + expect(overlayContainerElement.textContent).toContain('Slider value: 13'); + + tick(400); + })); + }); + describe('setting value', () => { let testBed: ComponentBed; let fixture: ComponentFixture; @@ -1191,6 +1231,19 @@ class NzTestSliderKeyboardComponent { disabled = false; } +@Component({ + template: ` + + + Slider value: {{ value }} + + ` +}) +class SliderShowTemplateTooltipComponent { + show: NzSliderShowTooltip = 'default'; + value = 0; +} + /** * Dispatches a click event sequence (consisting of moueseenter, click) from an element. * Note: The mouse event truncates the position for the click. diff --git a/components/tooltip/tooltip.ts b/components/tooltip/tooltip.ts index a145b7ce53..a55c2b534e 100644 --- a/components/tooltip/tooltip.ts +++ b/components/tooltip/tooltip.ts @@ -80,7 +80,7 @@ export class NzTooltipDirective extends NzTooltipBaseDirective { return { ...super.getProxyPropertyMap(), nzTooltipColor: ['nzColor', () => this.nzTooltipColor], - nzTooltipTitleContext: ['nzTitleContext', () => this.titleContext] + titleContext: ['nzTitleContext', () => this.titleContext] }; } }