diff --git a/components/tree-select/demo/module b/components/tree-select/demo/module index c896578d01..9e31c4d770 100644 --- a/components/tree-select/demo/module +++ b/components/tree-select/demo/module @@ -1,5 +1,7 @@ import { NzTreeSelectModule } from 'ng-zorro-antd/tree-select'; import { NzIconModule } from 'ng-zorro-antd/icon'; import { FormsModule } from '@angular/forms'; +import { NzSpaceModule } from 'ng-zorro-antd/space'; -export const moduleList = [ FormsModule, NzTreeSelectModule, NzIconModule ]; + +export const moduleList = [ FormsModule, NzTreeSelectModule, NzIconModule , NzSpaceModule]; diff --git a/components/tree-select/demo/status.md b/components/tree-select/demo/status.md new file mode 100644 index 0000000000..aacb6372fa --- /dev/null +++ b/components/tree-select/demo/status.md @@ -0,0 +1,15 @@ +--- +order: 8 +title: + zh-CN: 自定义状态 + en-US: Status +--- + +## zh-CN + +使用 `nzStatus` 为 `TreeSelect` 添加状态,可选 `error` 或者 `warning`。 + +## en-US + +Add status to TreeSelect with `nzStatus`, which could be `error` or `warning`. + diff --git a/components/tree-select/demo/status.ts b/components/tree-select/demo/status.ts new file mode 100644 index 0000000000..3cddfdbf71 --- /dev/null +++ b/components/tree-select/demo/status.ts @@ -0,0 +1,31 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'nz-demo-tree-select-status', + template: ` + + + + + ` +}) +export class NzDemoTreeSelectStatusComponent { + value?: string; + nodes = []; +} diff --git a/components/tree-select/doc/index.en-US.md b/components/tree-select/doc/index.en-US.md index d5ab594f32..3ed2ee1f15 100755 --- a/components/tree-select/doc/index.en-US.md +++ b/components/tree-select/doc/index.en-US.md @@ -35,6 +35,7 @@ import { NzTreeSelectModule } from 'ng-zorro-antd/tree-select'; | `[nzMultiple]` | Support multiple or not, will be `true` when enable `nzCheckable`. | `boolean` | `false` | | `[nzHideUnMatched]` | Hide unmatched nodes while searching | `boolean` | `false` | ✅ | | `[nzSize]` | To set the size of the select input | `'large' \| 'small' \| 'default'` | `'default'` | ✅ | +| `[nzStatus]` | Set validation status | `'error' \| 'warning'` | - | | | `[nzCheckable]` | Whether to show checkbox on the treeNodes | `boolean` | `false` | | `[nzCheckStrictly]` | Check treeNode precisely; parent treeNode and children treeNodes are not associated | `boolean` | `false` | | `[nzShowExpand]` | Show a Expand Icon before the treeNodes | `boolean` | `true` | | diff --git a/components/tree-select/doc/index.zh-CN.md b/components/tree-select/doc/index.zh-CN.md index 05c394e175..b7000b3e34 100755 --- a/components/tree-select/doc/index.zh-CN.md +++ b/components/tree-select/doc/index.zh-CN.md @@ -35,6 +35,7 @@ import { NzTreeSelectModule } from 'ng-zorro-antd/tree-select'; | `[nzMultiple]` | 支持多选(当设置 nzCheckable 时自动变为true) | `boolean` | `false` | | `[nzHideUnMatched]` | 搜索隐藏未匹配的节点 | `boolean` | `false` | ✅ | | `[nzSize]` | 选择框大小 | `'large' \| 'small' \| 'default'` | `'default'` | ✅ | +| `[nzStatus]` | 设置校验状态 | `'error' \| 'warning'` | - | | | `[nzCheckable]` | 节点前添加 Checkbox 复选框 | `boolean` | `false` | | `[nzCheckStrictly]` | checkable 状态下节点选择完全受控(父子节点选中状态不再关联) | `boolean` | `false` | | `[nzShowExpand]` | 节点前添加展开图标 | `boolean` | `true` | | diff --git a/components/tree-select/tree-select.component.ts b/components/tree-select/tree-select.component.ts index 83814013f2..13bcd9a2a7 100644 --- a/components/tree-select/tree-select.component.ts +++ b/components/tree-select/tree-select.component.ts @@ -44,8 +44,16 @@ import { NzTreeNode, NzTreeNodeOptions } from 'ng-zorro-antd/core/tree'; -import { BooleanInput, NgStyleInterface, NzSizeLDSType, OnChangeType, OnTouchedType } from 'ng-zorro-antd/core/types'; -import { InputBoolean, isNotNil } from 'ng-zorro-antd/core/util'; +import { + BooleanInput, + NgClassInterface, + NgStyleInterface, + NzSizeLDSType, + NzStatus, + OnChangeType, + OnTouchedType +} from 'ng-zorro-antd/core/types'; +import { getStatusClassNames, InputBoolean, isNotNil } from 'ng-zorro-antd/core/util'; import { NzSelectSearchComponent } from 'ng-zorro-antd/select'; import { NzTreeComponent } from 'ng-zorro-antd/tree'; @@ -253,6 +261,7 @@ export class NzTreeSelectComponent extends NzTreeBase implements ControlValueAcc @Input() nzDropdownStyle: NgStyleInterface | null = null; @Input() nzDropdownClassName?: string; @Input() @WithConfig() nzBackdrop = false; + @Input() nzStatus: NzStatus = ''; @Input() set nzExpandedKeys(value: string[]) { this.expandedKeys = value; @@ -285,6 +294,10 @@ export class NzTreeSelectComponent extends NzTreeBase implements ControlValueAcc return this.nzTreeTemplate || this.nzTreeTemplateChild; } + prefixCls: string = 'ant-select'; + statusCls: NgClassInterface = {}; + nzHasFeedback: boolean = false; + dropdownClassName = TREE_SELECT_DEFAULT_CLASS; triggerWidth?: number; isComposing = false; @@ -370,8 +383,20 @@ export class NzTreeSelectComponent extends NzTreeBase implements ControlValueAcc this.closeDropDown(); } + private setStatusStyles(): void { + // render status if nzStatus is set + this.statusCls = getStatusClassNames(this.prefixCls, this.nzStatus, this.nzHasFeedback); + Object.keys(this.statusCls).forEach(status => { + if (this.statusCls[status]) { + this.renderer.addClass(this.elementRef.nativeElement, status); + } else { + this.renderer.removeClass(this.elementRef.nativeElement, status); + } + }); + } + ngOnChanges(changes: SimpleChanges): void { - const { nzNodes, nzDropdownClassName } = changes; + const { nzNodes, nzDropdownClassName, nzStatus } = changes; if (nzNodes) { this.updateSelectedNodes(true); } @@ -379,6 +404,9 @@ export class NzTreeSelectComponent extends NzTreeBase implements ControlValueAcc const className = this.nzDropdownClassName && this.nzDropdownClassName.trim(); this.dropdownClassName = className ? `${TREE_SELECT_DEFAULT_CLASS} ${className}` : TREE_SELECT_DEFAULT_CLASS; } + if (nzStatus) { + this.setStatusStyles(); + } } writeValue(value: string[] | string): void { diff --git a/components/tree-select/tree-select.spec.ts b/components/tree-select/tree-select.spec.ts index d81879092a..96c7cd91ea 100644 --- a/components/tree-select/tree-select.spec.ts +++ b/components/tree-select/tree-select.spec.ts @@ -16,6 +16,7 @@ import { typeInElement } from 'ng-zorro-antd/core/testing'; import { NzTreeNode, NzTreeNodeOptions } from 'ng-zorro-antd/core/tree'; +import { NzStatus } from 'ng-zorro-antd/core/types'; import { NzTreeSelectComponent } from './tree-select.component'; import { NzTreeSelectModule } from './tree-select.module'; @@ -33,7 +34,8 @@ describe('tree-select component', () => { NzTestTreeSelectBasicComponent, NzTestTreeSelectCheckableComponent, NzTestTreeSelectFormComponent, - NzTestTreeSelectCustomizedIconComponent + NzTestTreeSelectCustomizedIconComponent, + NzTestTreeSelectStatusComponent ], providers: [ { @@ -606,6 +608,29 @@ describe('tree-select component', () => { expect(overlayContainerElement.querySelector('i.anticon.anticon-frown-o')).toBeTruthy(); })); }); + + describe('Status', () => { + let fixture: ComponentFixture; + let treeSelect: DebugElement; + + beforeEach(() => { + fixture = TestBed.createComponent(NzTestTreeSelectStatusComponent); + treeSelect = fixture.debugElement.query(By.directive(NzTreeSelectComponent)); + }); + + it('should className correct', () => { + fixture.detectChanges(); + expect(treeSelect.nativeElement.className).toContain('ant-select-status-error'); + + fixture.componentInstance.status = 'warning'; + fixture.detectChanges(); + expect(treeSelect.nativeElement.className).toContain('ant-select-status-warning'); + + fixture.componentInstance.status = ''; + fixture.detectChanges(); + expect(treeSelect.nativeElement.className).not.toContain('ant-select-status-warning'); + }); + }); }); @Component({ @@ -863,3 +888,41 @@ export class NzTestTreeSelectCustomizedIconComponent { }) ]; } + +@Component({ + template: ` + + ` +}) +export class NzTestTreeSelectStatusComponent { + status: NzStatus = 'error'; + value?: string = '1001'; + nodes = [ + { + title: 'parent 1', + key: '100', + children: [ + { + title: 'parent 1-0', + key: '1001', + children: [ + { title: 'leaf 1-0-0', key: '10010', isLeaf: true }, + { title: 'leaf 1-0-1', key: '10011', isLeaf: true } + ] + }, + { + title: 'parent 1-1', + key: '1002', + children: [{ title: 'leaf 1-1-0', key: '10020', isLeaf: true }] + } + ] + } + ]; +}