diff --git a/components/tree-select/demo/customized-selected-node.md b/components/tree-select/demo/customized-selected-node.md new file mode 100644 index 00000000000..b01a3d7c0e0 --- /dev/null +++ b/components/tree-select/demo/customized-selected-node.md @@ -0,0 +1,14 @@ +--- +order: 10 +title: + zh-CN: 自定义图标 + en-US: Custom Top Render +--- + +## zh-CN + +通过 `nzSelectedTemplate` 自定义 nz-tree-select 显示的内容。 + +## en-US + +Custom the content of nz-tree-select via `nzSelectedTemplate`. \ No newline at end of file diff --git a/components/tree-select/demo/customized-selected-node.ts b/components/tree-select/demo/customized-selected-node.ts new file mode 100644 index 00000000000..583594c25a2 --- /dev/null +++ b/components/tree-select/demo/customized-selected-node.ts @@ -0,0 +1,61 @@ +import { Component } from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +import { NzTreeNodeOptions } from 'ng-zorro-antd/core/tree'; +import { NzIconModule } from 'ng-zorro-antd/icon'; +import { NzTreeSelectModule } from 'ng-zorro-antd/tree-select'; + +function createNodes(): NzTreeNodeOptions[] { + return [ + { + title: 'parent 1', + key: '100', + expanded: true, + icon: 'smile', + children: [ + { title: 'leaf 1-0-0', key: '10010', icon: 'meh', isLeaf: true }, + { title: 'leaf 1-0-1', key: '10011', icon: 'frown', isLeaf: true } + ] + } + ]; +} + +@Component({ + selector: 'nz-demo-tree-select-customized-selected-node', + imports: [FormsModule, NzIconModule, NzTreeSelectModule], + template: ` + +
+ + + + + + + {{ node.title }} + + + + ` +}) +export class NzDemoTreeSelectCustomizedSelectedNodeComponent { + value?: string; + readonly nodes1 = createNodes(); + + multipleValue?: string[]; + readonly nodes2 = createNodes(); +} diff --git a/components/tree-select/doc/index.en-US.md b/components/tree-select/doc/index.en-US.md index fd706158231..8111df4c429 100755 --- a/components/tree-select/doc/index.en-US.md +++ b/components/tree-select/doc/index.en-US.md @@ -49,6 +49,7 @@ import { NzTreeSelectModule } from 'ng-zorro-antd/tree-select'; | `[nzMaxTagCount]` | Max tag count to show | number | - | | `[nzMaxTagPlaceholder]` | Placeholder for not showing tags | TemplateRef<{ $implicit: NzTreeNode[] }> | - | | `[nzTreeTemplate]` | Custom Nodes | `TemplateRef<{ $implicit: NzTreeNode }>` | - | +| `[nzSelectedTemplate]` | The custom template of select | `TemplateRef<{ $implicit: NzTreeNode }>` | - | | `[nzVirtualHeight]` | The height of virtual scroll | `string` | `-` | | `[nzVirtualItemSize]` | The size of the items in the list, same as [cdk itemSize](https://material.angular.io/cdk/scrolling/api) | `number` | `28` | | `[nzVirtualMaxBufferPx]` | The number of pixels worth of buffer to render for when rendering new items, same as [cdk maxBufferPx](https://material.angular.io/cdk/scrolling/api) | `number` | `500` | diff --git a/components/tree-select/doc/index.zh-CN.md b/components/tree-select/doc/index.zh-CN.md index b5b629a5028..39df5ca79c0 100755 --- a/components/tree-select/doc/index.zh-CN.md +++ b/components/tree-select/doc/index.zh-CN.md @@ -49,6 +49,7 @@ import { NzTreeSelectModule } from 'ng-zorro-antd/tree-select'; | `[nzMaxTagCount]` | 最多显示多少个 tag | number | - | | `[nzMaxTagPlaceholder]` | 隐藏 tag 时显示的内容 | TemplateRef<{ $implicit: NzTreeNode[] }> | - | | `[nzTreeTemplate]` | 自定义节点 | `TemplateRef<{ $implicit: NzTreeNode }>` | - | +| `[nzSelectedTemplate]` | 自定义选择框的 Template 内容 | `TemplateRef<{ $implicit: NzTreeNode }>` | - | | `[nzVirtualHeight]` | 虚拟滚动的总高度 | `string` | `-` | | `[nzVirtualItemSize]` | 虚拟滚动时每一列的高度,与 [cdk itemSize](https://material.angular.io/cdk/scrolling/api) 相同 | `number` | `28` | | `[nzVirtualMaxBufferPx]` | 缓冲区最大像素高度,与 [cdk maxBufferPx](https://material.angular.io/cdk/scrolling/api) 相同 | `number` | `500` | diff --git a/components/tree-select/tree-select.component.ts b/components/tree-select/tree-select.component.ts index 4905d3dee05..73216e36730 100644 --- a/components/tree-select/tree-select.component.ts +++ b/components/tree-select/tree-select.component.ts @@ -170,6 +170,8 @@ const listOfPositions = [ [deletable]="true" [disabled]="node.isDisabled || nzDisabled" [label]="nzDisplayWith(node)" + [contentTemplateOutlet]="selectedItemTemplate" + [contentTemplateOutletContext]="node" (delete)="removeSelected(node, true)" > } @@ -208,6 +210,8 @@ const listOfPositions = [ [deletable]="false" [disabled]="false" [label]="nzDisplayWith(selectedNodes[0])" + [contentTemplateOutlet]="selectedItemTemplate" + [contentTemplateOutletContext]="selectedNodes[0]" > } @@ -325,6 +329,15 @@ export class NzTreeSelectComponent extends NzTreeBase implements ControlValueAcc return this.nzTreeTemplate || this.nzTreeTemplateChild; } + @Input() nzSelectedTemplate!: TemplateRef<{ $implicit: NzTreeNode; origin: NzTreeNodeOptions }>; + @ContentChild('nzSelectedTemplate', { static: true }) nzSelectedTemplateChild!: TemplateRef<{ + $implicit: NzTreeNode; + origin: NzTreeNodeOptions; + }>; + get selectedItemTemplate(): TemplateRef<{ $implicit: NzTreeNode; origin: NzTreeNodeOptions }> { + return this.nzSelectedTemplate || this.nzSelectedTemplateChild; + } + prefixCls: string = 'ant-select'; statusCls: NgClassInterface = {}; status: NzValidateStatus = ''; diff --git a/components/tree-select/tree-select.spec.ts b/components/tree-select/tree-select.spec.ts index 330a226b324..ff68db46b71 100644 --- a/components/tree-select/tree-select.spec.ts +++ b/components/tree-select/tree-select.spec.ts @@ -2,7 +2,7 @@ import { BACKSPACE } from '@angular/cdk/keycodes'; import { OverlayContainer } from '@angular/cdk/overlay'; import { TestKey } from '@angular/cdk/testing'; import { UnitTestElement } from '@angular/cdk/testing/testbed'; -import { Component, DebugElement, NgZone, ViewChild } from '@angular/core'; +import { Component, DebugElement, NgZone, TemplateRef, ViewChild } from '@angular/core'; import { ComponentFixture, fakeAsync, flush, inject, TestBed, tick, waitForAsync } from '@angular/core/testing'; import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { By } from '@angular/platform-browser'; @@ -16,7 +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 { NzSafeAny, NzStatus } from 'ng-zorro-antd/core/types'; import { NzFormControlStatusType, NzFormModule } from 'ng-zorro-antd/form'; import { NzTreeSelectComponent } from './tree-select.component'; @@ -349,6 +349,22 @@ describe('tree-select component', () => { expect(treeSelectComponent.isComposing).toBe(true); expect(treeSelectComponent.inputValue).toBe(''); })); + + it('should nzSelectedTemplate works', fakeAsync(() => { + testComponent.setNull(); + fixture.detectChanges(); + tick(); + fixture.detectChanges(); + tick(); + fixture.detectChanges(); + expect(treeSelect.nativeElement.querySelector('nz-select-item')).toBeFalsy(); + testComponent.value = '100012'; + testComponent.nzSelectedTemplate = testComponent.selectedTemplate; + fixture.detectChanges(); + flush(); + fixture.detectChanges(); + expect(treeSelect.nativeElement.querySelector('nz-select-item')!.textContent?.trim()).toBe(`selected: child1.2`); + })); }); describe('checkable', () => { @@ -678,18 +694,22 @@ describe('tree-select component', () => { [nzMaxTagCount]="maxTagCount" [nzDropdownStyle]="{ height: '120px' }" [nzBackdrop]="hasBackdrop" + [nzSelectedTemplate]="nzSelectedTemplate ?? null" nzDropdownClassName="class1 class2" > + selected: {{ selected.title }} ` }) export class NzTestTreeSelectBasicComponent { @ViewChild(NzTreeSelectComponent, { static: false }) nzSelectTreeComponent!: NzTreeSelectComponent; + @ViewChild('selectedTemplate') selectedTemplate!: TemplateRef; expandKeys = ['1001', '10001']; value: string | string[] | null = '10001'; size = 'default'; allowClear = false; disabled = false; showSearch = false; + nzSelectedTemplate?: TemplateRef<{ $implicit: NzTreeNode }>; dropdownMatchSelectWidth = true; multiple = false; maxTagCount = Infinity;