Skip to content

Commit 0d8249b

Browse files
authored
feat(module:time-picker): support setting status (#7473)
* feat(module:time-picker): support setting status * feat(module:time-picker): add tests
1 parent c3d0874 commit 0d8249b

File tree

7 files changed

+115
-6
lines changed

7 files changed

+115
-6
lines changed

components/time-picker/demo/module

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { NzTimePickerModule } from 'ng-zorro-antd/time-picker';
22
import { NzButtonModule } from 'ng-zorro-antd/button';
3+
import { NzSpaceModule } from 'ng-zorro-antd/space';
34

4-
export const moduleList = [ NzTimePickerModule, NzButtonModule ];
5+
export const moduleList = [ NzTimePickerModule, NzButtonModule, NzSpaceModule ];

components/time-picker/demo/status.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
order: 10
3+
title:
4+
zh-CN: 自定义状态
5+
en-US: Status
6+
---
7+
8+
## zh-CN
9+
10+
使用 `nzStatus` 为 TimePicker 添加状态,可选 `error` 或者 `warning`
11+
12+
## en-US
13+
14+
Add status to TimePicker with `nzStatus`, which could be `error` or `warning`.

components/time-picker/demo/status.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Component } from '@angular/core';
2+
3+
@Component({
4+
selector: 'nz-demo-time-picker-status',
5+
template: `
6+
<nz-space nzDirection="vertical">
7+
<nz-time-picker *nzSpaceItem nzStatus="error"></nz-time-picker>
8+
<nz-time-picker *nzSpaceItem nzStatus="warning">></nz-time-picker>
9+
</nz-space>
10+
`
11+
})
12+
export class NzDemoTimePickerStatusComponent {}

components/time-picker/doc/index.en-US.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ import { NzTimePickerModule } from 'ng-zorro-antd/time-picker';
4444
| `[nzHourStep]` | interval between hours in picker | `number` | `1` ||
4545
| `[nzMinuteStep]` | interval between minutes in picker | `number` | `1` ||
4646
| `[nzSecondStep]` | interval between seconds in picker | `number` | `1` ||
47+
| `[nzSize]` | width of time picker box | `'large' \| 'small' \| 'default'` | `'default'` |
48+
| `[nzStatus]` | Set validation status | `'error' \| 'warning'` | - |
4749
| `[nzOpen]` | whether to popup panel, double binding | `boolean` | `false` |
4850
| `[nzPlaceHolder]` | display when there's no value | `string` | `"Select a time"` |
4951
| `[nzPopupClassName]` | className of panel | `string` | `''` ||

components/time-picker/doc/index.zh-CN.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ import { NzTimePickerModule } from 'ng-zorro-antd/time-picker';
4545
| `[nzHourStep]` | 小时选项间隔 | `number` | `1` ||
4646
| `[nzMinuteStep]` | 分钟选项间隔 | `number` | `1` ||
4747
| `[nzSecondStep]` | 秒选项间隔 | `number` | `1` ||
48+
| `[nzSize]` | 时间选择框大小 | `'large'\|'small'\|'default'` | `'default'` |
49+
| `[nzStatus]` | 设置校验状态 | `'error' \| 'warning'` | - |
4850
| `[nzOpen]` | 面板是否打开,可双向绑定 | `boolean` | `false` |
4951
| `[nzPlaceHolder]` | 没有值的时候显示的内容 | `string` | `"请选择时间"` |
5052
| `[nzPopupClassName]` | 弹出层类名 | `string` | `''` ||

components/time-picker/time-picker.component.spec.ts

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { BidiModule, Direction } from '@angular/cdk/bidi';
12
import { OverlayContainer } from '@angular/cdk/overlay';
23
import { registerLocaleData } from '@angular/common';
34
import zh from '@angular/common/locales/zh';
@@ -8,6 +9,7 @@ import { By } from '@angular/platform-browser';
89
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
910

1011
import { dispatchFakeEvent, dispatchMouseEvent, typeInElement } from 'ng-zorro-antd/core/testing';
12+
import { NzStatus } from 'ng-zorro-antd/core/types';
1113
import { PREFIX_CLASS } from 'ng-zorro-antd/date-picker';
1214
import { getPickerInput, getPickerOkButton } from 'ng-zorro-antd/date-picker/testing/util';
1315

@@ -24,9 +26,9 @@ describe('time-picker', () => {
2426
beforeEach(
2527
waitForAsync(() => {
2628
TestBed.configureTestingModule({
27-
imports: [NoopAnimationsModule, FormsModule, NzI18nModule, NzTimePickerModule],
29+
imports: [BidiModule, NoopAnimationsModule, FormsModule, NzI18nModule, NzTimePickerModule],
2830
schemas: [NO_ERRORS_SCHEMA],
29-
declarations: [NzTestTimePickerComponent]
31+
declarations: [NzTestTimePickerComponent, NzTestTimePickerStatusComponent, NzTestTimePickerDirComponent]
3032
});
3133
TestBed.compileComponents();
3234
inject([OverlayContainer], (oc: OverlayContainer) => {
@@ -292,6 +294,48 @@ describe('time-picker', () => {
292294
});
293295
});
294296

297+
describe('time-picker status', () => {
298+
let testComponent: NzTestTimePickerStatusComponent;
299+
let fixture: ComponentFixture<NzTestTimePickerStatusComponent>;
300+
let timeElement: DebugElement;
301+
beforeEach(() => {
302+
fixture = TestBed.createComponent(NzTestTimePickerStatusComponent);
303+
testComponent = fixture.debugElement.componentInstance;
304+
fixture.detectChanges();
305+
timeElement = fixture.debugElement.query(By.directive(NzTimePickerComponent));
306+
});
307+
it('should className correct with nzStatus', () => {
308+
fixture.detectChanges();
309+
expect(timeElement.nativeElement.classList).toContain('ant-picker-status-error');
310+
311+
testComponent.status = 'warning';
312+
fixture.detectChanges();
313+
expect(timeElement.nativeElement.className).toContain('ant-picker-status-warning');
314+
315+
testComponent.status = '';
316+
fixture.detectChanges();
317+
expect(timeElement.nativeElement.className).not.toContain('ant-picker-status-warning');
318+
});
319+
});
320+
321+
describe('time-picker RTL', () => {
322+
let testComponent: NzTestTimePickerDirComponent;
323+
let fixture: ComponentFixture<NzTestTimePickerDirComponent>;
324+
let timeElement: DebugElement;
325+
beforeEach(() => {
326+
fixture = TestBed.createComponent(NzTestTimePickerDirComponent);
327+
testComponent = fixture.debugElement.componentInstance;
328+
fixture.detectChanges();
329+
timeElement = fixture.debugElement.query(By.directive(NzTimePickerComponent));
330+
});
331+
it('should className correct on dir change', () => {
332+
expect(timeElement.nativeElement.classList).not.toContain('ant-picker-rtl');
333+
testComponent.dir = 'rtl';
334+
fixture.detectChanges();
335+
expect(timeElement.nativeElement.classList).toContain('ant-picker-rtl');
336+
});
337+
});
338+
295339
function queryFromOverlay(selector: string): HTMLElement {
296340
return overlayContainerElement.querySelector(selector) as HTMLElement;
297341
}
@@ -334,3 +378,17 @@ export class NzTestTimePickerComponent {
334378
onChange(_: Date | null): void {}
335379
@ViewChild(NzTimePickerComponent, { static: false }) nzTimePickerComponent!: NzTimePickerComponent;
336380
}
381+
382+
@Component({
383+
template: ` <nz-time-picker [nzStatus]="status"></nz-time-picker> `
384+
})
385+
export class NzTestTimePickerStatusComponent {
386+
status: NzStatus = 'error';
387+
}
388+
389+
@Component({
390+
template: ` <div [dir]="dir"><nz-time-picker></nz-time-picker></div> `
391+
})
392+
export class NzTestTimePickerDirComponent {
393+
dir: Direction = 'ltr';
394+
}

components/time-picker/time-picker.component.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ import { isValid } from 'date-fns';
3434
import { slideMotion } from 'ng-zorro-antd/core/animation';
3535
import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config';
3636
import { warn } from 'ng-zorro-antd/core/logger';
37-
import { BooleanInput, NzSafeAny } from 'ng-zorro-antd/core/types';
38-
import { InputBoolean, isNil } from 'ng-zorro-antd/core/util';
37+
import { BooleanInput, NgClassInterface, NzSafeAny, NzStatus } from 'ng-zorro-antd/core/types';
38+
import { getStatusClassNames, InputBoolean, isNil } from 'ng-zorro-antd/core/util';
3939
import { DateHelperService, NzI18nInterface, NzI18nService } from 'ng-zorro-antd/i18n';
4040

4141
const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'timePicker';
@@ -176,10 +176,15 @@ export class NzTimePickerComponent implements ControlValueAccessor, OnInit, Afte
176176
}
177177
] as ConnectionPositionPair[];
178178
dir: Direction = 'ltr';
179+
// status
180+
prefixCls: string = 'ant-picker';
181+
statusCls: NgClassInterface = {};
182+
hasFeedback: boolean = false;
179183

180184
@ViewChild('inputElement', { static: true }) inputRef!: ElementRef<HTMLInputElement>;
181185
@Input() nzId: string | null = null;
182186
@Input() nzSize: string | null = null;
187+
@Input() nzStatus?: NzStatus;
183188
@Input() @WithConfig() nzHourStep: number = 1;
184189
@Input() @WithConfig() nzMinuteStep: number = 1;
185190
@Input() @WithConfig() nzSecondStep: number = 1;
@@ -347,7 +352,7 @@ export class NzTimePickerComponent implements ControlValueAccessor, OnInit, Afte
347352
}
348353

349354
ngOnChanges(changes: SimpleChanges): void {
350-
const { nzUse12Hours, nzFormat, nzDisabled, nzAutoFocus } = changes;
355+
const { nzUse12Hours, nzFormat, nzDisabled, nzAutoFocus, nzStatus } = changes;
351356
if (nzUse12Hours && !nzUse12Hours.previousValue && nzUse12Hours.currentValue && !nzFormat) {
352357
this.nzFormat = 'h:mm:ss a';
353358
}
@@ -363,6 +368,9 @@ export class NzTimePickerComponent implements ControlValueAccessor, OnInit, Afte
363368
if (nzAutoFocus) {
364369
this.updateAutoFocus();
365370
}
371+
if (nzStatus) {
372+
this.setStatusStyles();
373+
}
366374
}
367375

368376
parseTimeString(str: string): void {
@@ -421,4 +429,16 @@ export class NzTimePickerComponent implements ControlValueAccessor, OnInit, Afte
421429
disabledSeconds?.includes(value.getSeconds())
422430
);
423431
}
432+
433+
private setStatusStyles(): void {
434+
// render status if nzStatus is set
435+
this.statusCls = getStatusClassNames(this.prefixCls, this.nzStatus, this.hasFeedback);
436+
Object.keys(this.statusCls).forEach(status => {
437+
if (this.statusCls[status]) {
438+
this.renderer.addClass(this.element.nativeElement, status);
439+
} else {
440+
this.renderer.removeClass(this.element.nativeElement, status);
441+
}
442+
});
443+
}
424444
}

0 commit comments

Comments
 (0)