Skip to content

Commit

Permalink
feat(module:cascader): support suffix icon & expand icon (#5899)
Browse files Browse the repository at this point in the history
* feat(module:cascader): support suffix icon & expand icon

close #5885

* docs: add doc

* test: add test
  • Loading branch information
Wendell Hu authored Oct 23, 2020
1 parent 93c0d46 commit d235589
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 31 deletions.
9 changes: 8 additions & 1 deletion components/cascader/cascader-li.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ import { NzCascaderOption } from './typings';
<span [innerHTML]="optionLabel | nzHighlight: highlightText:'g':'ant-cascader-menu-item-keyword'"></span>
</ng-template>
<span *ngIf="!option.isLeaf || option.children?.length || option.loading" class="ant-cascader-menu-item-expand-icon">
<i nz-icon [nzType]="option.loading ? 'loading' : 'right'"></i>
<i *ngIf="option.loading; else icon" nz-icon nzType="loading"></i>
<ng-template #icon>
<ng-container *nzStringTemplateOutlet="expandIcon">
<i nz-icon [nzType]="$any(expandIcon)"></i>
</ng-container>
</ng-template>
</span>
`,
host: {
Expand All @@ -47,6 +52,8 @@ export class NzCascaderOptionComponent {
@Input() nzLabelProperty = 'label';
@Input() columnIndex!: number;

@Input() expandIcon: string | TemplateRef<void> = 'right';

constructor(private cdr: ChangeDetectorRef, elementRef: ElementRef, renderer: Renderer2) {
renderer.addClass(elementRef.nativeElement, 'ant-cascader-menu-item');
}
Expand Down
20 changes: 13 additions & 7 deletions components/cascader/cascader.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,15 @@ const defaultDisplayRender = (labels: string[]) => labels.join(' / ');
class="ant-cascader-picker-clear"
(click)="clearSelection($event)"
></i>
<i
*ngIf="nzShowArrow && !isLoading"
nz-icon
nzType="down"
class="ant-cascader-picker-arrow"
[class.ant-cascader-picker-arrow-expand]="menuVisible"
></i>
<ng-container *nzStringTemplateOutlet="nzSuffixIcon">
<i
*ngIf="nzShowArrow && !isLoading"
nz-icon
[nzType]="$any(nzSuffixIcon)"
class="ant-cascader-picker-arrow"
[class.ant-cascader-picker-arrow-expand]="menuVisible"
></i>
</ng-container>
<i *ngIf="isLoading" nz-icon nzType="loading" class="ant-cascader-picker-arrow"></i>
<span
class="ant-cascader-picker-label"
Expand Down Expand Up @@ -150,6 +152,7 @@ const defaultDisplayRender = (labels: string[]) => labels.join(' / ');
<li
nz-cascader-option
*ngFor="let option of options"
[expandIcon]="nzExpandIcon"
[columnIndex]="i"
[nzLabelProperty]="nzLabelProperty"
[optionTemplate]="nzOptionRender"
Expand Down Expand Up @@ -221,6 +224,9 @@ export class NzCascaderComponent implements NzCascaderComponentAsSource, OnInit,
@Input() nzTriggerAction: NzCascaderTriggerType | NzCascaderTriggerType[] = ['click'] as NzCascaderTriggerType[];
@Input() nzChangeOn?: (option: NzCascaderOption, level: number) => boolean;
@Input() nzLoadData?: (node: NzCascaderOption, index: number) => PromiseLike<NzSafeAny>;
// TODO: RTL
@Input() nzSuffixIcon: string | TemplateRef<void> = 'down';
@Input() nzExpandIcon: string | TemplateRef<void> = 'right';

@Input()
get nzOptions(): NzCascaderOption[] | null {
Expand Down
43 changes: 30 additions & 13 deletions components/cascader/cascader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { createFakeEvent, createMouseEvent, dispatchKeyboardEvent, dispatchMouseEvent } from 'ng-zorro-antd/core/testing';
import { NzIconTestModule } from 'ng-zorro-antd/icon/testing';

import { NzCascaderComponent } from './cascader.component';
import { NzCascaderModule } from './cascader.module';
Expand Down Expand Up @@ -61,7 +62,7 @@ describe('cascader', () => {
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
imports: [FormsModule, ReactiveFormsModule, NoopAnimationsModule, NzCascaderModule],
imports: [FormsModule, ReactiveFormsModule, NoopAnimationsModule, NzCascaderModule, NzIconTestModule],
declarations: [NzDemoCascaderDefaultComponent],
providers: []
}).compileComponents();
Expand Down Expand Up @@ -619,7 +620,7 @@ describe('cascader', () => {
expect(control.labelRenderText).toBe('Zhejiang');
}));

it('should write value work on setting `nzOptions` asyn (match)', fakeAsync(() => {
it('should write value work on setting `nzOptions` async (match)', fakeAsync(() => {
const control = testComponent.cascader;
testComponent.nzOptions = null;
testComponent.values = ['zhejiang', 'hangzhou', 'xihu'];
Expand All @@ -637,7 +638,7 @@ describe('cascader', () => {
expect(control.labelRenderText).toBe('Zhejiang / Hangzhou / West Lake');
}));

it('should write value work on setting `nzOptions` asyn (not match)', fakeAsync(() => {
it('should write value work on setting `nzOptions` async (not match)', fakeAsync(() => {
const control = testComponent.cascader;
testComponent.nzOptions = null;
testComponent.values = ['zhejiang2', 'hangzhou2', 'xihu2'];
Expand Down Expand Up @@ -1543,6 +1544,18 @@ describe('cascader', () => {
itemEl1 = getItemAtColumnAndRow(1, 1)!;
expect(itemEl1.innerText).toBe('Option1 / Option11');
});

it('should support changing icon', () => {
testComponent.nzSuffixIcon = 'home';
testComponent.nzExpandIcon = 'home';

fixture.detectChanges();
testComponent.cascader.setMenuVisible(true);
fixture.detectChanges();
const itemEl1 = getItemAtColumnAndRow(1, 1);
expect(itemEl1?.querySelector('.anticon-home')).toBeTruthy();
expect(cascader.nativeElement.querySelector('.ant-cascader-picker-arrow')!.classList).toContain('anticon-home');
});
});

describe('load data lazily', () => {
Expand Down Expand Up @@ -1911,28 +1924,30 @@ const options5: any[] = []; // tslint:disable-line:no-any
@Component({
template: `
<nz-cascader
[nzOptions]="nzOptions"
[(ngModel)]="values"
[nzAllowClear]="nzAllowClear"
[nzAutoFocus]="nzAutoFocus"
[nzMenuStyle]="nzMenuStyle"
[nzMenuClassName]="nzMenuClassName"
[nzChangeOn]="nzChangeOn"
[nzChangeOnSelect]="nzChangeOnSelect"
[nzColumnClassName]="nzColumnClassName"
[nzExpandTrigger]="nzExpandTrigger"
[nzDisabled]="nzDisabled"
[nzLabelRender]="nzLabelRender"
[nzExpandIcon]="nzExpandIcon"
[nzExpandTrigger]="nzExpandTrigger"
[nzLabelProperty]="nzLabelProperty"
[nzValueProperty]="nzValueProperty"
[nzLabelRender]="nzLabelRender"
[nzMenuClassName]="nzMenuClassName"
[nzMenuStyle]="nzMenuStyle"
[nzMouseEnterDelay]="nzMouseEnterDelay"
[nzMouseLeaveDelay]="nzMouseLeaveDelay"
[nzOptions]="nzOptions"
[nzPlaceHolder]="nzPlaceHolder"
[nzShowArrow]="nzShowArrow"
[nzShowInput]="nzShowInput"
[nzShowSearch]="nzShowSearch"
[nzSize]="nzSize"
[nzTriggerAction]="nzTriggerAction"
[nzMouseEnterDelay]="nzMouseEnterDelay"
[nzMouseLeaveDelay]="nzMouseLeaveDelay"
[nzChangeOn]="nzChangeOn"
[nzChangeOnSelect]="nzChangeOnSelect"
[nzSuffixIcon]="nzSuffixIcon"
[nzValueProperty]="nzValueProperty"
(ngModelChange)="onValueChanges($event)"
(nzVisibleChange)="onVisibleChange($event)"
(nzSelect)="onSelect($event)"
Expand Down Expand Up @@ -1977,6 +1992,8 @@ export class NzDemoCascaderDefaultComponent {
nzTriggerAction: string | string[] = 'click';
nzMouseEnterDelay = 150; // ms
nzMouseLeaveDelay = 150; // ms
nzSuffixIcon = 'down';
nzExpandIcon = 'right';

onVisibleChange = jasmine.createSpy('open change');
onValueChanges = jasmine.createSpy('value change');
Expand Down
12 changes: 8 additions & 4 deletions components/cascader/demo/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,15 @@ const otherOptions = [
@Component({
selector: 'nz-demo-cascader-basic',
template: `
<nz-cascader [nzOptions]="nzOptions" [(ngModel)]="values" (ngModelChange)="onChanges($event)"></nz-cascader>
<nz-cascader
nzSuffixIcon="eye"
nzExpandIcon="eye"
[nzOptions]="nzOptions"
[(ngModel)]="values"
(ngModelChange)="onChanges($event)"
></nz-cascader>
&nbsp;
<a href="javascript:;" (click)="changeNzOptions()" class="change-options">
Change Options
</a>
<a href="javascript:;" (click)="changeNzOptions()" class="change-options">Change Options</a>
`,
styles: [
`
Expand Down
8 changes: 5 additions & 3 deletions components/cascader/doc/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,22 @@ import { NzCascaderModule } from 'ng-zorro-antd/cascader';
| `[nzChangeOnSelect]` | change value on each selection if set to true, see above demo for details | `boolean` | `false` |
| `[nzColumnClassName]` | additional className of column in the popup overlay | `string` | - |
| `[nzDisabled]` | whether disabled select | `boolean` | `false` |
| `[nzExpandIcon]` | Customize the current item expand icon | `string\|TemplateRef<void>` | - |
| `[nzExpandTrigger]` | expand current item when click or hover, one of 'click' 'hover' | `'click'\|'hover'` | `'click'` |
| `[nzLabelProperty]` | the label property name of options | `string` | `'label'` |
| `[nzLabelRender]` | render template of displaying selected options | `TemplateRef<any>` | - |
| `[nzLoadData]` | To load option lazily. If setting `ngModel` with an array value and `nzOptions` is not setting, lazy load will be call immediately | `(option: any, index?: index) => PromiseLike<any>` | - |
| `[nzMenuClassName]` | additional className of popup overlay | `string` | - |
| `[nzMenuStyle]` | additional css style of popup overlay | `object` | - |
| `[nzNotFoundContent]` | Specify content to show when no result matches. | `string\|TemplateRef<void>` | - |
| `[nzLabelProperty]` | the label property name of options | `string` | `'label'` |
| `[nzLabelRender]` | render template of displaying selected options | `TemplateRef<any>` | - |
| `[nzOptionRender]` | render template of cascader options | `TemplateRef<{ $implicit: NzCascaderOption, index: number }>` | |
| `[nzLoadData]` | To load option lazily. If setting `ngModel` with an array value and `nzOptions` is not setting, lazy load will be call immediately | `(option: any, index?: index) => PromiseLike<any>` | - |
| `[nzOptions]` | data options of cascade | `object[]` | - |
| `[nzPlaceHolder]` | input placeholder | `string` | `'Please select'` |
| `[nzShowArrow]` | Whether show arrow | `boolean` | `true` |
| `[nzShowInput]` | Whether show input | `boolean` | `true` |
| `[nzShowSearch]` | Whether support search. Cannot be used with `[nzLoadData]` at the same time | `boolean\|NzShowSearchOptions` | `false` |
| `[nzSize]` | input size, one of `large` `default` `small` | `'large'\|'small'\|'default'` | `'default'` ||
| `[nzSuffixIcon]` | The custom suffix icon | `string\|TemplateRef<void>` | - |
| `[nzValueProperty]` | the value property name of options | `string` | `'value'` |
| `(ngModelChange)` | Emit on values change | `EventEmitter<any[]>` | - |
| `(nzClear)` | Emit on clear values | `EventEmitter<void>` | - |
Expand Down
8 changes: 5 additions & 3 deletions components/cascader/doc/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,22 @@ import { NzCascaderModule } from 'ng-zorro-antd/cascader';
| `[nzChangeOnSelect]` | 当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的演示 | `boolean` | `false` |
| `[nzColumnClassName]` | 自定义浮层列类名 | `string` | - |
| `[nzDisabled]` | 禁用 | `boolean` | `false` |
| `[nzExpandIcon]` | 自定义次级菜单展开图标 | `string\|TemplateRef<void>` | - |
| `[nzExpandTrigger]` | 次级菜单的展开方式,可选 'click' 和 'hover' | `'click'\|'hover'` | `'click'` |
| `[nzLabelProperty]` | 选项的显示值的属性名 | `string` | `'label'` |
| `[nzLabelRender]` | 选择后展示的渲染模板 | `TemplateRef<any>` | - |
| `[nzLoadData]` | 用于动态加载选项。如果提供了`ngModel`初始值,且未提供`nzOptions`值,则会立即触发动态加载。 | `(option: any, index?: index) => PromiseLike<any>` | - |
| `[nzMenuClassName]` | 自定义浮层类名 | `string` | - |
| `[nzMenuStyle]` | 自定义浮层样式 | `object` | - |
| `[nzNotFoundContent]` | 当下拉列表为空时显示的内容 | `string\|TemplateRef<void>` | - |
| `[nzLabelProperty]` | 选项的显示值的属性名 | `string` | `'label'` |
| `[nzLabelRender]` | 选择后展示的渲染模板 | `TemplateRef<any>` | - |
| `[nzOptionRender]` | 选项的渲染模板 | `TemplateRef<{ $implicit: NzCascaderOption, index: number }>` | |
| `[nzLoadData]` | 用于动态加载选项。如果提供了`ngModel`初始值,且未提供`nzOptions`值,则会立即触发动态加载。 | `(option: any, index?: index) => PromiseLike<any>` | - |
| `[nzOptions]` | 可选项数据源 | `object[]` | - |
| `[nzPlaceHolder]` | 输入框占位文本 | `string` | `'请选择'` |
| `[nzShowArrow]` | 是否显示箭头 | `boolean` | `true` |
| `[nzShowInput]` | 显示输入框 | `boolean` | `true` |
| `[nzShowSearch]` | 是否支持搜索,默认情况下对 `label` 进行全匹配搜索,不能和 `[nzLoadData]` 同时使用 | `boolean\|NzShowSearchOptions` | `false` |
| `[nzSize]` | 输入框大小,可选 `large` `default` `small` | `'large'\|'small'\|'default'` | `'default'` ||
| `[nzSuffixIcon]` | 自定义的选择框后缀图标 | `string\|TemplateRef<void>` | - |
| `[nzValueProperty]` | 选项的实际值的属性名 | `string` | `'value'` |
| `(ngModelChange)` | 值发生变化时触发 | `EventEmitter<any[]>` | - |
| `(nzVisibleChange)` | 菜单浮层的显示/隐藏 | `EventEmitter<boolean>` | - |
Expand Down

0 comments on commit d235589

Please sign in to comment.