Skip to content

Commit

Permalink
refactor(module:cascader): implement new control flow (#8303)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicoss54 authored Dec 21, 2023
1 parent 57b853d commit dbe5b0d
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 102 deletions.
33 changes: 18 additions & 15 deletions components/cascader/cascader-li.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { Direction } from '@angular/cdk/bidi';
import { NgIf, NgTemplateOutlet } from '@angular/common';
import { NgTemplateOutlet } from '@angular/common';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Expand All @@ -28,26 +28,29 @@ import { NzCascaderOption } from './typings';
selector: '[nz-cascader-option]',
exportAs: 'nzCascaderOption',
template: `
<ng-container *ngIf="optionTemplate; else defaultOptionTemplate">
@if (optionTemplate) {
<ng-template
[ngTemplateOutlet]="optionTemplate"
[ngTemplateOutletContext]="{ $implicit: option, index: columnIndex }"
></ng-template>
</ng-container>
<ng-template #defaultOptionTemplate>
/>
} @else {
<div
class="ant-cascader-menu-item-content"
[innerHTML]="optionLabel | nzHighlight: highlightText : 'g' : 'ant-cascader-menu-item-keyword'"
></div>
</ng-template>
<div *ngIf="!option.isLeaf || option.children?.length || option.loading" class="ant-cascader-menu-item-expand-icon">
<span *ngIf="option.loading; else icon" nz-icon nzType="loading"></span>
<ng-template #icon>
<ng-container *nzStringTemplateOutlet="expandIcon">
<span nz-icon [nzType]="$any(expandIcon)"></span>
</ng-container>
</ng-template>
</div>
}
@if (!option.isLeaf || option.children?.length || option.loading) {
<div class="ant-cascader-menu-item-expand-icon">
@if (option.loading) {
<span nz-icon nzType="loading"></span>
} @else {
<ng-container *nzStringTemplateOutlet="expandIcon">
<span nz-icon [nzType]="$any(expandIcon)"></span>
</ng-container>
}
</div>
}
`,
host: {
class: 'ant-cascader-menu-item ant-cascader-menu-item-expanded',
Expand All @@ -56,7 +59,7 @@ import { NzCascaderOption } from './typings';
'[class.ant-cascader-menu-item-expand]': '!option.isLeaf',
'[class.ant-cascader-menu-item-disabled]': 'option.disabled'
},
imports: [NgIf, NgTemplateOutlet, NzHighlightModule, NzIconModule, NzOutletModule],
imports: [NgTemplateOutlet, NzHighlightModule, NzIconModule, NzOutletModule],
standalone: true
})
export class NzCascaderOptionComponent implements OnInit {
Expand Down
148 changes: 75 additions & 73 deletions components/cascader/cascader.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { Direction, Directionality } from '@angular/cdk/bidi';
import { BACKSPACE, DOWN_ARROW, ENTER, ESCAPE, LEFT_ARROW, RIGHT_ARROW, UP_ARROW } from '@angular/cdk/keycodes';
import { CdkConnectedOverlay, ConnectionPositionPair, OverlayModule } from '@angular/cdk/overlay';
import { NgClass, NgForOf, NgIf, NgStyle, NgTemplateOutlet } from '@angular/common';
import { NgClass, NgStyle, NgTemplateOutlet } from '@angular/common';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Expand Down Expand Up @@ -78,7 +78,7 @@ const defaultDisplayRender = (labels: string[]): string => labels.join(' / ');
preserveWhitespaces: false,
template: `
<div cdkOverlayOrigin #origin="cdkOverlayOrigin" #trigger>
<ng-container *ngIf="nzShowInput">
@if (nzShowInput) {
<div #selectContainer class="ant-select-selector">
<span class="ant-select-selection-search">
<input
Expand All @@ -96,36 +96,42 @@ const defaultDisplayRender = (labels: string[]): string => labels.join(' / ');
(focus)="handleInputFocus()"
/>
</span>
<span *ngIf="showLabelRender" class="ant-select-selection-item" [title]="labelRenderText">
<ng-container *ngIf="!isLabelRenderTemplate; else labelTemplate">{{ labelRenderText }}</ng-container>
<ng-template #labelTemplate>
<ng-template
[ngTemplateOutlet]="nzLabelRender"
[ngTemplateOutletContext]="labelRenderContext"
></ng-template>
</ng-template>
</span>
<span
*ngIf="!showLabelRender"
class="ant-select-selection-placeholder"
[style.visibility]="!inputValue ? 'visible' : 'hidden'"
>{{ showPlaceholder ? nzPlaceHolder || locale?.placeholder : null }}</span
>
@if (showLabelRender) {
<span class="ant-select-selection-item" [title]="labelRenderText">
@if (!isLabelRenderTemplate) {
<ng-container>{{ labelRenderText }}</ng-container>
} @else {
<ng-template
[ngTemplateOutlet]="nzLabelRender"
[ngTemplateOutletContext]="labelRenderContext"
></ng-template>
}
</span>
} @else {
<span class="ant-select-selection-placeholder" [style.visibility]="!inputValue ? 'visible' : 'hidden'">{{
showPlaceholder ? nzPlaceHolder || locale?.placeholder : null
}}</span>
}
</div>
<span class="ant-select-arrow" [class.ant-select-arrow-loading]="isLoading" *ngIf="nzShowArrow">
<span
*ngIf="!isLoading"
nz-icon
[nzType]="$any(nzSuffixIcon)"
[class.ant-cascader-picker-arrow-expand]="menuVisible"
></span>
<span *ngIf="isLoading" nz-icon nzType="loading"></span>
<nz-form-item-feedback-icon *ngIf="hasFeedback && !!status" [status]="status"></nz-form-item-feedback-icon>
</span>
<span class="ant-select-clear" *ngIf="clearIconVisible">
<span nz-icon nzType="close-circle" nzTheme="fill" (click)="clearSelection($event)"></span>
</span>
</ng-container>
@if (nzShowArrow) {
<span class="ant-select-arrow" [class.ant-select-arrow-loading]="isLoading">
@if (!isLoading) {
<span nz-icon [nzType]="$any(nzSuffixIcon)" [class.ant-cascader-picker-arrow-expand]="menuVisible"></span>
} @else {
<span nz-icon nzType="loading"></span>
}
@if (hasFeedback && !!status) {
<nz-form-item-feedback-icon [status]="status" />
}
</span>
}
@if (clearIconVisible) {
<span class="ant-select-clear">
<span nz-icon nzType="close-circle" nzTheme="fill" (click)="clearSelection($event)"></span>
</span>
}
}
<ng-content></ng-content>
</div>
<ng-template
Expand Down Expand Up @@ -157,46 +163,44 @@ const defaultDisplayRender = (labels: string[]): string => labels.join(' / ');
[ngClass]="menuCls"
[ngStyle]="nzMenuStyle"
>
<ul
*ngIf="shouldShowEmpty; else hasOptionsTemplate"
class="ant-cascader-menu"
[style.width]="dropdownWidthStyle"
[style.height]="dropdownHeightStyle"
>
<li class="ant-cascader-menu-item ant-cascader-menu-item-disabled">
<nz-embed-empty
class="ant-cascader-menu-item-content"
[nzComponentName]="'cascader'"
[specificContent]="nzNotFoundContent"
></nz-embed-empty>
</li>
</ul>
<ng-template #hasOptionsTemplate>
<ul
*ngFor="let options of cascaderService.columns; let i = index"
class="ant-cascader-menu"
role="menuitemcheckbox"
[ngClass]="menuColumnCls"
[style.height]="dropdownHeightStyle"
[style.width]="dropdownWidthStyle"
>
<li
nz-cascader-option
*ngFor="let option of options"
[expandIcon]="nzExpandIcon"
[columnIndex]="i"
[nzLabelProperty]="nzLabelProperty"
[optionTemplate]="nzOptionRender"
[activated]="isOptionActivated(option, i)"
[highlightText]="inSearchingMode ? inputValue : ''"
[option]="option"
[dir]="dir"
(mouseenter)="onOptionMouseEnter(option, i, $event)"
(mouseleave)="onOptionMouseLeave(option, i, $event)"
(click)="onOptionClick(option, i, $event)"
></li>
@if (shouldShowEmpty) {
<ul class="ant-cascader-menu" [style.width]="dropdownWidthStyle" [style.height]="dropdownHeightStyle">
<li class="ant-cascader-menu-item ant-cascader-menu-item-disabled">
<nz-embed-empty
class="ant-cascader-menu-item-content"
[nzComponentName]="'cascader'"
[specificContent]="nzNotFoundContent"
/>
</li>
</ul>
</ng-template>
} @else {
@for (options of cascaderService.columns; track options; let i = $index) {
<ul
class="ant-cascader-menu"
role="menuitemcheckbox"
[ngClass]="menuColumnCls"
[style.height]="dropdownHeightStyle"
[style.width]="dropdownWidthStyle"
>
@for (option of options; track option.value) {
<li
nz-cascader-option
[expandIcon]="nzExpandIcon"
[columnIndex]="i"
[nzLabelProperty]="nzLabelProperty"
[optionTemplate]="nzOptionRender"
[activated]="isOptionActivated(option, i)"
[highlightText]="inSearchingMode ? inputValue : ''"
[option]="option"
[dir]="dir"
(mouseenter)="onOptionMouseEnter(option, i, $event)"
(mouseleave)="onOptionMouseLeave(option, i, $event)"
(click)="onOptionClick(option, i, $event)"
></li>
}
</ul>
}
}
</div>
</div>
</ng-template>
Expand Down Expand Up @@ -227,7 +231,6 @@ const defaultDisplayRender = (labels: string[]): string => labels.join(' / ');
},
imports: [
OverlayModule,
NgIf,
FormsModule,
NgTemplateOutlet,
NzIconModule,
Expand All @@ -237,8 +240,7 @@ const defaultDisplayRender = (labels: string[]): string => labels.join(' / ');
NgClass,
NgStyle,
NzEmptyModule,
NzCascaderOptionComponent,
NgForOf
NzCascaderOptionComponent
],
standalone: true
})
Expand Down
8 changes: 4 additions & 4 deletions components/cascader/cascader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
} from '@angular/cdk/keycodes';
import { OverlayContainer } from '@angular/cdk/overlay';
import { Component, DebugElement, TemplateRef, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed, fakeAsync, flush, inject, tick, waitForAsync } from '@angular/core/testing';
import { ComponentFixture, fakeAsync, flush, inject, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
Expand Down Expand Up @@ -2106,9 +2106,9 @@ const options5: any[] = []; // eslint-disable-line @typescript-eslint/no-explici
></nz-cascader>
<ng-template #renderTpl let-labels="labels" let-selectedOptions="selectedOptions">
<ng-container *ngFor="let label of labels; let i = index; let isLast = last">
{{ label }}{{ isLast ? '' : ' | ' }}
</ng-container>
@for (label of labels; track label) {
{{ label }}{{ $last ? '' : ' | ' }}
}
</ng-template>
`,
styles: [
Expand Down
23 changes: 13 additions & 10 deletions components/cascader/demo/custom-render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,19 @@ const options = [
></nz-cascader>
<ng-template #renderTpl let-labels="labels" let-selectedOptions="selectedOptions">
<ng-container *ngFor="let label of labels; let i = index; let isLast = last">
<span *ngIf="!isLast">{{ label }} /</span>
<span *ngIf="isLast">
{{ label }} (
<a href="javascript:;" (click)="handleAreaClick($event, label, selectedOptions[i])">
{{ selectedOptions[i].code }}
</a>
)
</span>
</ng-container>
@for (label of labels; track label) {
@if (!$last) {
<span>{{ label }} /</span>
} @else {
<span>
{{ label }} (
<a href="javascript:;" (click)="handleAreaClick($event, label, selectedOptions[$index])">
{{ selectedOptions[$index].code }}
</a>
)
</span>
}
}
</ng-template>
`
})
Expand Down

0 comments on commit dbe5b0d

Please sign in to comment.