diff --git a/components/slider/demo/reverse.md b/components/slider/demo/reverse.md
new file mode 100644
index 00000000000..ed922d9013a
--- /dev/null
+++ b/components/slider/demo/reverse.md
@@ -0,0 +1,15 @@
+---
+order: 8
+title:
+ zh-CN: 反向
+ en-US: Reverse
+---
+
+## zh-CN
+
+设置 `nzReverse` 可以将滑动条置反。
+
+## en-US
+
+Using `nzReverse` to render slider reversely.
+
diff --git a/components/slider/demo/reverse.ts b/components/slider/demo/reverse.ts
new file mode 100644
index 00000000000..80d7105f29e
--- /dev/null
+++ b/components/slider/demo/reverse.ts
@@ -0,0 +1,26 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'nz-demo-slider-reverse',
+ template: `
+
+
+
+ Reversed:
+
+ `,
+ styles: [
+ `
+ h4 {
+ margin: 0 0 16px;
+ }
+
+ .ant-slider-with-marks {
+ margin-bottom: 44px;
+ }
+ `
+ ]
+})
+export class NzDemoSliderReverseComponent {
+ reverse = true;
+}
diff --git a/components/slider/doc/index.en-US.md b/components/slider/doc/index.en-US.md
index 5b291942cff..3ad0095dff4 100644
--- a/components/slider/doc/index.en-US.md
+++ b/components/slider/doc/index.en-US.md
@@ -31,6 +31,7 @@ import { NzSliderModule } from 'ng-zorro-antd/slider';
| `[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` | - |
| `[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` |
| `[nzTooltipVisible]` | When set to `always` tooltips are always displayed. When set to `never` they are never displayed | `'default' \| 'always' \| 'never'` | `default` |
| `[nzTooltipPlacement]` | Set the default placement of Tooltip | `string` | |
| `(nzOnAfterChange)` | Fire when `onmouseup` is fired. | `EventEmitter` | - |
diff --git a/components/slider/doc/index.zh-CN.md b/components/slider/doc/index.zh-CN.md
index 208178863d0..16b4a0fd463 100644
--- a/components/slider/doc/index.zh-CN.md
+++ b/components/slider/doc/index.zh-CN.md
@@ -32,6 +32,7 @@ import { NzSliderModule } from 'ng-zorro-antd/slider';
| `[nzTipFormatter]` | Slider 会把当前值传给 `nzTipFormatter`,并在 Tooltip 中显示 `nzTipFormatter` 的返回值,若为 null,则隐藏 Tooltip。 | `(value: number) => string` | - |
| `[ngModel]` | 设置当前取值。当 `range` 为 `false` 时,使用 `number`,否则用 `[number, number]` | `number \| number[]` | - |
| `[nzVertical]` | 值为 `true` 时,Slider 为垂直方向 | `boolean` | `false` |
+| `[nzReverse]` | 反向坐标轴 | `boolean` | `false` |
| `[nzTooltipVisible]` | 值为 `always` 时总是显示,值为 `never` 时在任何情况下都不显示 | `'default' \| 'always' \| 'never'` | `default` |
| `[nzTooltipPlacement]` | 设置 Tooltip 的默认位置。 | `string` | |
| `(nzOnAfterChange)` | 与 `onmouseup` 触发时机一致,把当前值作为参数传入。 | `EventEmitter` | - |
diff --git a/components/slider/handle.component.ts b/components/slider/handle.component.ts
index 41aab659101..3e9b7d4715c 100644
--- a/components/slider/handle.component.ts
+++ b/components/slider/handle.component.ts
@@ -54,6 +54,7 @@ export class NzSliderHandleComponent implements OnChanges {
@ViewChild(NzTooltipDirective, { static: false }) tooltip: NzTooltipDirective;
@Input() vertical: string;
+ @Input() reverse: string;
@Input() offset: number;
@Input() value: number;
@Input() tooltipVisible: NzSliderShowTooltip = 'default';
@@ -67,9 +68,9 @@ export class NzSliderHandleComponent implements OnChanges {
constructor(private sliderService: NzSliderService, private cdr: ChangeDetectorRef) {}
ngOnChanges(changes: SimpleChanges): void {
- const { offset, value, active, tooltipVisible } = changes;
+ const { offset, value, active, tooltipVisible, reverse } = changes;
- if (offset) {
+ if (offset || reverse) {
this.updateStyle();
}
@@ -133,10 +134,23 @@ export class NzSliderHandleComponent implements OnChanges {
}
private updateStyle(): void {
- this.style = {
- [this.vertical ? 'bottom' : 'left']: `${this.offset}%`,
- transform: this.vertical ? 'translateY(50%)' : 'translateX(-50%)'
- };
+ const vertical = this.vertical;
+ const reverse = this.reverse;
+ const offset = this.offset;
+
+ const positionStyle = vertical
+ ? {
+ [reverse ? 'top' : 'bottom']: `${offset}%`,
+ [reverse ? 'bottom' : 'top']: 'auto',
+ transform: reverse ? null : `translateY(+50%)`
+ }
+ : {
+ [reverse ? 'right' : 'left']: `${offset}%`,
+ [reverse ? 'left' : 'right']: 'auto',
+ transform: `translateX(${reverse ? '+' : '-'}50%)`
+ };
+
+ this.style = positionStyle;
this.cdr.markForCheck();
}
}
diff --git a/components/slider/slider.component.ts b/components/slider/slider.component.ts
index dc769ca03b1..a4a48562d3e 100644
--- a/components/slider/slider.component.ts
+++ b/components/slider/slider.component.ts
@@ -73,7 +73,13 @@ import { NzExtendedMark, NzMarks, NzSliderHandler, NzSliderShowTooltip, NzSlider
[class.ant-slider-with-marks]="marksArray"
>
-
+
{
let sliderInstance: NzSliderComponent;
let overlayContainerElement: HTMLElement;
- // tslint:disable-next-line:no-any
- function getReferenceFromFixture(fixture: ComponentFixture): void {
+ function getReferenceFromFixture(fixture: ComponentFixture): void {
sliderDebugElement = fixture.debugElement.query(By.directive(NzSliderComponent));
sliderInstance = sliderDebugElement.componentInstance;
sliderNativeElement = sliderInstance.slider.nativeElement;
@@ -491,6 +491,49 @@ describe('nz-slider', () => {
});
});
+ describe('reverse', () => {
+ let testBed: ComponentBed;
+ let fixture: ComponentFixture;
+ let sliderDebugElements: DebugElement[];
+
+ beforeEach(() => {
+ testBed = createComponentBed(ReverseSliderComponent, {
+ imports: [NzSliderModule, FormsModule, ReactiveFormsModule, NoopAnimationsModule]
+ });
+ fixture = testBed.fixture;
+ fixture.detectChanges();
+
+ sliderDebugElements = fixture.debugElement.queryAll(By.directive(NzSliderComponent));
+ });
+
+ it('should reverse work', () => {
+ const trackElement = (sliderDebugElements[0].nativeElement as HTMLElement).querySelector('.ant-slider-track') as HTMLElement;
+ expect(trackElement.style.right).toBe('0%');
+
+ const rangeTrackElement = (sliderDebugElements[1].nativeElement as HTMLElement).querySelector('.ant-slider-track') as HTMLElement;
+ expect(trackElement.style.right).toBe('0%');
+ expect(rangeTrackElement.style.width).toBe('100%');
+
+ const verticalTrackElement = (sliderDebugElements[2].nativeElement as HTMLElement).querySelector('.ant-slider-track') as HTMLElement;
+ expect(verticalTrackElement.style.top).toBe('0%');
+ });
+
+ it('should respond to keyboard event reversely', () => {
+ getReferenceFromFixture(fixture);
+
+ dispatchKeyboardEvent(sliderNativeElement, 'keydown', LEFT_ARROW);
+ dispatchKeyboardEvent(sliderNativeElement, 'keydown', RIGHT_ARROW);
+ dispatchKeyboardEvent(sliderNativeElement, 'keydown', DOWN_ARROW);
+ dispatchKeyboardEvent(sliderNativeElement, 'keydown', UP_ARROW);
+ dispatchKeyboardEvent(sliderNativeElement, 'keydown', LEFT_ARROW);
+
+ fixture.detectChanges();
+
+ const trackElement = (sliderDebugElements[0].nativeElement as HTMLElement).querySelector('.ant-slider-track') as HTMLElement;
+ expect(trackElement.style.width).toBe('1%');
+ });
+ });
+
describe('mixed usage', () => {
let testBed: ComponentBed;
let fixture: ComponentFixture;
@@ -743,18 +786,14 @@ const styles = `
`;
@Component({
- template: `
-
- `,
+ template: ` `,
styles: [styles]
})
class NzTestSliderComponent {
disabled = false;
}
@Component({
- template: `
-
- `,
+ template: ` `,
styles: [styles]
})
class SliderWithMinAndMaxComponent {
@@ -763,17 +802,13 @@ class SliderWithMinAndMaxComponent {
}
@Component({
- template: `
-
- `,
+ template: ` `,
styles: [styles]
})
class SliderWithValueComponent {}
@Component({
- template: `
-
- `,
+ template: ` `,
styles: [styles]
})
class SliderWithStepComponent {
@@ -781,29 +816,32 @@ class SliderWithStepComponent {
}
@Component({
- template: `
-
- `,
+ template: ` `,
styles: [styles]
})
class SliderWithValueSmallerThanMinComponent {}
@Component({
- template: `
-
- `,
+ template: ` `,
styles: [styles]
})
class SliderWithValueGreaterThanMaxComponent {}
@Component({
- template: `
-
- `,
+ template: ` `,
styles: [styles]
})
class VerticalSliderComponent {}
+@Component({
+ template: `
+
+
+
+ `
+})
+class ReverseSliderComponent {}
+
@Component({
template: `
- `
+ template: ` `
})
class SliderShowTooltipComponent {
show: NzSliderShowTooltip = 'default';
@@ -860,9 +896,7 @@ class SliderShowTooltipComponent {
}
@Component({
- template: `
-
- `
+ template: ` `
})
class NzTestSliderKeyboardComponent {
range = false;
diff --git a/components/slider/track.component.ts b/components/slider/track.component.ts
index 0403d08abac..30ed316468a 100644
--- a/components/slider/track.component.ts
+++ b/components/slider/track.component.ts
@@ -6,9 +6,8 @@
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
-import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges, ViewEncapsulation } from '@angular/core';
+import { ChangeDetectionStrategy, Component, Input, OnChanges, ViewEncapsulation } from '@angular/core';
import { BooleanInput, NumberInput } from 'ng-zorro-antd/core/types';
-
import { InputBoolean, InputNumber } from 'ng-zorro-antd/core/util';
export interface NzSliderTrackStyle {
@@ -34,28 +33,34 @@ export class NzSliderTrackComponent implements OnChanges {
static ngAcceptInputType_included: BooleanInput;
@Input() @InputNumber() offset: number;
+ @Input() @InputBoolean() reverse: boolean = false;
@Input() @InputNumber() length: number;
@Input() @InputBoolean() vertical = false;
@Input() @InputBoolean() included = false;
style: NzSliderTrackStyle = {};
- ngOnChanges(changes: SimpleChanges): void {
- if (changes.included) {
- this.style.visibility = this.included ? 'visible' : 'hidden';
- }
- if (changes.vertical || changes.offset || changes.length) {
- if (this.vertical) {
- this.style.bottom = `${this.offset}%`;
- this.style.height = `${this.length}%`;
- this.style.left = null;
- this.style.width = null;
- } else {
- this.style.left = `${this.offset}%`;
- this.style.width = `${this.length}%`;
- this.style.bottom = null;
- this.style.height = null;
- }
- }
+ ngOnChanges(): void {
+ const vertical = this.vertical;
+ const reverse = this.reverse;
+ const visibility = this.included ? 'visible' : 'hidden';
+ const offset = this.offset;
+ const length = this.length;
+
+ const positonStyle: NzSliderTrackStyle = vertical
+ ? {
+ [reverse ? 'top' : 'bottom']: `${offset}%`,
+ [reverse ? 'bottom' : 'top']: 'auto',
+ height: `${length}%`,
+ visibility
+ }
+ : {
+ [reverse ? 'right' : 'left']: `${offset}%`,
+ [reverse ? 'left' : 'right']: 'auto',
+ width: `${length}%`,
+ visibility
+ };
+
+ this.style = positonStyle;
}
}