Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(module:time-picker): support setting status #7473

Merged
merged 2 commits into from
May 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion components/time-picker/demo/module
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { NzTimePickerModule } from 'ng-zorro-antd/time-picker';
import { NzButtonModule } from 'ng-zorro-antd/button';
import { NzSpaceModule } from 'ng-zorro-antd/space';

export const moduleList = [ NzTimePickerModule, NzButtonModule ];
export const moduleList = [ NzTimePickerModule, NzButtonModule, NzSpaceModule ];
14 changes: 14 additions & 0 deletions components/time-picker/demo/status.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
order: 10
title:
zh-CN: 自定义状态
en-US: Status
---

## zh-CN

使用 `nzStatus` 为 TimePicker 添加状态,可选 `error` 或者 `warning`。

## en-US

Add status to TimePicker with `nzStatus`, which could be `error` or `warning`.
12 changes: 12 additions & 0 deletions components/time-picker/demo/status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Component } from '@angular/core';

@Component({
selector: 'nz-demo-time-picker-status',
template: `
<nz-space nzDirection="vertical">
<nz-time-picker *nzSpaceItem nzStatus="error"></nz-time-picker>
<nz-time-picker *nzSpaceItem nzStatus="warning">></nz-time-picker>
</nz-space>
`
})
export class NzDemoTimePickerStatusComponent {}
2 changes: 2 additions & 0 deletions components/time-picker/doc/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ import { NzTimePickerModule } from 'ng-zorro-antd/time-picker';
| `[nzHourStep]` | interval between hours in picker | `number` | `1` | ✅ |
| `[nzMinuteStep]` | interval between minutes in picker | `number` | `1` | ✅ |
| `[nzSecondStep]` | interval between seconds in picker | `number` | `1` | ✅ |
| `[nzSize]` | width of time picker box | `'large' \| 'small' \| 'default'` | `'default'` |
| `[nzStatus]` | Set validation status | `'error' \| 'warning'` | - |
| `[nzOpen]` | whether to popup panel, double binding | `boolean` | `false` |
| `[nzPlaceHolder]` | display when there's no value | `string` | `"Select a time"` |
| `[nzPopupClassName]` | className of panel | `string` | `''` | ✅ |
Expand Down
2 changes: 2 additions & 0 deletions components/time-picker/doc/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import { NzTimePickerModule } from 'ng-zorro-antd/time-picker';
| `[nzHourStep]` | 小时选项间隔 | `number` | `1` | ✅ |
| `[nzMinuteStep]` | 分钟选项间隔 | `number` | `1` | ✅ |
| `[nzSecondStep]` | 秒选项间隔 | `number` | `1` | ✅ |
| `[nzSize]` | 时间选择框大小 | `'large'\|'small'\|'default'` | `'default'` |
| `[nzStatus]` | 设置校验状态 | `'error' \| 'warning'` | - |
| `[nzOpen]` | 面板是否打开,可双向绑定 | `boolean` | `false` |
| `[nzPlaceHolder]` | 没有值的时候显示的内容 | `string` | `"请选择时间"` |
| `[nzPopupClassName]` | 弹出层类名 | `string` | `''` | ✅ |
Expand Down
62 changes: 60 additions & 2 deletions components/time-picker/time-picker.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { BidiModule, Direction } from '@angular/cdk/bidi';
import { OverlayContainer } from '@angular/cdk/overlay';
import { registerLocaleData } from '@angular/common';
import zh from '@angular/common/locales/zh';
Expand All @@ -8,6 +9,7 @@ import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';

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

Expand All @@ -24,9 +26,9 @@ describe('time-picker', () => {
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
imports: [NoopAnimationsModule, FormsModule, NzI18nModule, NzTimePickerModule],
imports: [BidiModule, NoopAnimationsModule, FormsModule, NzI18nModule, NzTimePickerModule],
schemas: [NO_ERRORS_SCHEMA],
declarations: [NzTestTimePickerComponent]
declarations: [NzTestTimePickerComponent, NzTestTimePickerStatusComponent, NzTestTimePickerDirComponent]
});
TestBed.compileComponents();
inject([OverlayContainer], (oc: OverlayContainer) => {
Expand Down Expand Up @@ -292,6 +294,48 @@ describe('time-picker', () => {
});
});

describe('time-picker status', () => {
let testComponent: NzTestTimePickerStatusComponent;
let fixture: ComponentFixture<NzTestTimePickerStatusComponent>;
let timeElement: DebugElement;
beforeEach(() => {
fixture = TestBed.createComponent(NzTestTimePickerStatusComponent);
testComponent = fixture.debugElement.componentInstance;
fixture.detectChanges();
timeElement = fixture.debugElement.query(By.directive(NzTimePickerComponent));
});
it('should className correct with nzStatus', () => {
fixture.detectChanges();
expect(timeElement.nativeElement.classList).toContain('ant-picker-status-error');

testComponent.status = 'warning';
fixture.detectChanges();
expect(timeElement.nativeElement.className).toContain('ant-picker-status-warning');

testComponent.status = '';
fixture.detectChanges();
expect(timeElement.nativeElement.className).not.toContain('ant-picker-status-warning');
});
});

describe('time-picker RTL', () => {
let testComponent: NzTestTimePickerDirComponent;
let fixture: ComponentFixture<NzTestTimePickerDirComponent>;
let timeElement: DebugElement;
beforeEach(() => {
fixture = TestBed.createComponent(NzTestTimePickerDirComponent);
testComponent = fixture.debugElement.componentInstance;
fixture.detectChanges();
timeElement = fixture.debugElement.query(By.directive(NzTimePickerComponent));
});
it('should className correct on dir change', () => {
expect(timeElement.nativeElement.classList).not.toContain('ant-picker-rtl');
testComponent.dir = 'rtl';
fixture.detectChanges();
expect(timeElement.nativeElement.classList).toContain('ant-picker-rtl');
});
});

function queryFromOverlay(selector: string): HTMLElement {
return overlayContainerElement.querySelector(selector) as HTMLElement;
}
Expand Down Expand Up @@ -334,3 +378,17 @@ export class NzTestTimePickerComponent {
onChange(_: Date | null): void {}
@ViewChild(NzTimePickerComponent, { static: false }) nzTimePickerComponent!: NzTimePickerComponent;
}

@Component({
template: ` <nz-time-picker [nzStatus]="status"></nz-time-picker> `
})
export class NzTestTimePickerStatusComponent {
status: NzStatus = 'error';
}

@Component({
template: ` <div [dir]="dir"><nz-time-picker></nz-time-picker></div> `
})
export class NzTestTimePickerDirComponent {
dir: Direction = 'ltr';
}
26 changes: 23 additions & 3 deletions components/time-picker/time-picker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import { isValid } from 'date-fns';
import { slideMotion } from 'ng-zorro-antd/core/animation';
import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config';
import { warn } from 'ng-zorro-antd/core/logger';
import { BooleanInput, NzSafeAny } from 'ng-zorro-antd/core/types';
import { InputBoolean, isNil } from 'ng-zorro-antd/core/util';
import { BooleanInput, NgClassInterface, NzSafeAny, NzStatus } from 'ng-zorro-antd/core/types';
import { getStatusClassNames, InputBoolean, isNil } from 'ng-zorro-antd/core/util';
import { DateHelperService, NzI18nInterface, NzI18nService } from 'ng-zorro-antd/i18n';

const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'timePicker';
Expand Down Expand Up @@ -176,10 +176,15 @@ export class NzTimePickerComponent implements ControlValueAccessor, OnInit, Afte
}
] as ConnectionPositionPair[];
dir: Direction = 'ltr';
// status
prefixCls: string = 'ant-picker';
statusCls: NgClassInterface = {};
hasFeedback: boolean = false;

@ViewChild('inputElement', { static: true }) inputRef!: ElementRef<HTMLInputElement>;
@Input() nzId: string | null = null;
@Input() nzSize: string | null = null;
@Input() nzStatus?: NzStatus;
@Input() @WithConfig() nzHourStep: number = 1;
@Input() @WithConfig() nzMinuteStep: number = 1;
@Input() @WithConfig() nzSecondStep: number = 1;
Expand Down Expand Up @@ -347,7 +352,7 @@ export class NzTimePickerComponent implements ControlValueAccessor, OnInit, Afte
}

ngOnChanges(changes: SimpleChanges): void {
const { nzUse12Hours, nzFormat, nzDisabled, nzAutoFocus } = changes;
const { nzUse12Hours, nzFormat, nzDisabled, nzAutoFocus, nzStatus } = changes;
if (nzUse12Hours && !nzUse12Hours.previousValue && nzUse12Hours.currentValue && !nzFormat) {
this.nzFormat = 'h:mm:ss a';
}
Expand All @@ -363,6 +368,9 @@ export class NzTimePickerComponent implements ControlValueAccessor, OnInit, Afte
if (nzAutoFocus) {
this.updateAutoFocus();
}
if (nzStatus) {
this.setStatusStyles();
}
}

parseTimeString(str: string): void {
Expand Down Expand Up @@ -421,4 +429,16 @@ export class NzTimePickerComponent implements ControlValueAccessor, OnInit, Afte
disabledSeconds?.includes(value.getSeconds())
);
}

private setStatusStyles(): void {
// render status if nzStatus is set
this.statusCls = getStatusClassNames(this.prefixCls, this.nzStatus, this.hasFeedback);
Object.keys(this.statusCls).forEach(status => {
if (this.statusCls[status]) {
this.renderer.addClass(this.element.nativeElement, status);
} else {
this.renderer.removeClass(this.element.nativeElement, status);
}
});
}
}