From c742ea2531d0afb9f64ac306db109f75c27d4da2 Mon Sep 17 00:00:00 2001 From: Wendell Date: Thu, 9 Jan 2020 19:35:51 +0800 Subject: [PATCH] fix(module:cascader): fix not showing empty when there's no options (#4565) * fix(module:cascader): fix not showing empty when there's no options close #4562 * fix: fix style * fix: fix dropdown style when there's no search result * chore: remove garbage --- .../cascader/nz-cascader.component.html | 57 ++++++++++--------- components/cascader/nz-cascader.component.ts | 56 ++++++++++++------ components/cascader/nz-cascader.service.ts | 4 +- components/core/overlay/overlay-position.ts | 1 + 4 files changed, 73 insertions(+), 45 deletions(-) diff --git a/components/cascader/nz-cascader.component.html b/components/cascader/nz-cascader.component.html index 72412e46286..d286597348c 100644 --- a/components/cascader/nz-cascader.component.html +++ b/components/cascader/nz-cascader.component.html @@ -34,7 +34,8 @@ [class.ant-cascader-picker-arrow-expand]="menuVisible" > - + {{ labelRenderText - }} + }} -
    -
  • +
    • + class="ant-cascader-menu-item ant-cascader-menu-item-expanded ant-cascader-menu-item-disabled">
    + +
      +
    • +
    +
    diff --git a/components/cascader/nz-cascader.component.ts b/components/cascader/nz-cascader.component.ts index 661f8d90c90..f883177f81c 100644 --- a/components/cascader/nz-cascader.component.ts +++ b/components/cascader/nz-cascader.component.ts @@ -34,7 +34,7 @@ import { Subject } from 'rxjs'; import { startWith, takeUntil } from 'rxjs/operators'; import { - DEFAULT_DROPDOWN_POSITIONS, + DEFAULT_CASCADER_POSITIONS, InputBoolean, NgClassType, NgStyleInterface, @@ -42,7 +42,6 @@ import { NzNoAnimationDirective, slideMotion, toArray, - warnDeprecation, WithConfig } from 'ng-zorro-antd/core'; @@ -140,15 +139,15 @@ export class NzCascaderComponent implements NzCascaderComponentAsSource, OnInit, } @Output() readonly nzVisibleChange = new EventEmitter(); - @Output() readonly nzSelectionChange = new EventEmitter(); + @Output() readonly nzSelect = new EventEmitter<{ option: NzCascaderOption; index: number } | null>(); + @Output() readonly nzClear = new EventEmitter(); /** - * @deprecated 9.0.0. This api is a duplication of `ngModelChange`. + * If the dropdown should show the empty content. + * `true` if there's no options. */ - @Output() readonly nzSelect = new EventEmitter<{ option: NzCascaderOption; index: number } | null>(); - - @Output() readonly nzClear = new EventEmitter(); + shouldShowEmpty: boolean = false; el: HTMLElement; dropDownPosition = 'bottom'; @@ -158,8 +157,13 @@ export class NzCascaderComponent implements NzCascaderComponentAsSource, OnInit, labelRenderContext = {}; onChange = Function.prototype; onTouched = Function.prototype; - positions: ConnectionPositionPair[] = [...DEFAULT_DROPDOWN_POSITIONS]; + positions: ConnectionPositionPair[] = [...DEFAULT_CASCADER_POSITIONS]; + + /** + * Dropdown's with in pixel. + */ dropdownWidthStyle: string; + dropdownHeightStyle: 'auto' | '' = ''; isFocused = false; locale: NzCascaderI18nInterface; @@ -232,8 +236,10 @@ export class NzCascaderComponent implements NzCascaderComponentAsSource, OnInit, srv.$redraw.pipe(takeUntil(this.$destroy)).subscribe(() => { // These operations would not mutate data. this.checkChildren(); - this.buildDisplayLabel(); + this.setDisplayLabel(); this.reposition(); + this.setDropdownStyles(); + this.cdr.markForCheck(); }); @@ -264,9 +270,14 @@ export class NzCascaderComponent implements NzCascaderComponentAsSource, OnInit, this.dropdownWidthStyle = ''; }); - this.i18nService.localeChange.pipe(startWith(), takeUntil(this.$destroy)).subscribe(() => { - this.setLocale(); - }); + this.i18nService.localeChange + .pipe( + startWith(), + takeUntil(this.$destroy) + ) + .subscribe(() => { + this.setLocale(); + }); this.nzConfigService .getConfigChangeEventForComponent(NZ_CONFIG_COMPONENT_NAME) @@ -274,10 +285,6 @@ export class NzCascaderComponent implements NzCascaderComponentAsSource, OnInit, .subscribe(() => { this.cdr.markForCheck(); }); - - if (this.nzSelect.observers.length > 0) { - warnDeprecation(`nzSelect is deprecated and will be removed in 9.0.0. Please use 'nzSelectionChange' instead.`); - } } ngOnDestroy(): void { @@ -571,8 +578,8 @@ export class NzCascaderComponent implements NzCascaderComponentAsSource, OnInit, private toggleSearchingMode(toSearching: boolean): void { if (this.inSearchingMode !== toSearching) { this.cascaderService.toggleSearchingMode(toSearching); - this.dropdownWidthStyle = toSearching ? `${this.input.nativeElement.offsetWidth}px` : ''; } + if (this.inSearchingMode) { this.cascaderService.prepareSearchOptions(this.inputValue); } @@ -625,7 +632,7 @@ export class NzCascaderComponent implements NzCascaderComponentAsSource, OnInit, } } - private buildDisplayLabel(): void { + private setDisplayLabel(): void { const selectedOptions = this.cascaderService.selectedOptions; const labels: string[] = selectedOptions.map(o => this.cascaderService.getOptionLabel(o)); @@ -636,6 +643,19 @@ export class NzCascaderComponent implements NzCascaderComponentAsSource, OnInit, } } + private setDropdownStyles(): void { + const firstColumn = this.cascaderService.columns[0]; + + this.shouldShowEmpty = + (this.inSearchingMode && (!firstColumn || !firstColumn.length)) || // Should show empty when there's no searching result + (!(this.nzOptions && this.nzOptions.length) && !this.nzLoadData); // Should show when there's no options and developer does not use nzLoadData + this.dropdownHeightStyle = this.shouldShowEmpty ? 'auto' : ''; + + if (this.input) { + this.dropdownWidthStyle = this.inSearchingMode || this.shouldShowEmpty ? `${this.input.nativeElement.offsetWidth}px` : ''; + } + } + private setLocale(): void { this.locale = this.i18nService.getLocaleData('global'); this.cdr.markForCheck(); diff --git a/components/cascader/nz-cascader.service.ts b/components/cascader/nz-cascader.service.ts index cd0301c1b28..b607aa459db 100644 --- a/components/cascader/nz-cascader.service.ts +++ b/components/cascader/nz-cascader.service.ts @@ -29,7 +29,7 @@ export class NzCascaderService implements OnDestroy { activatedOptions: NzCascaderOption[] = []; /** An array to store cascader items arranged in different layers. */ - columns: NzCascaderOption[][] = [[]]; + columns: NzCascaderOption[][] = []; /** If user has entered searching mode. */ inSearchingMode = false; @@ -296,6 +296,8 @@ export class NzCascaderService implements OnDestroy { } this.columns = [results]; + + this.$redraw.next(); // Search results may be empty, so should redraw. } /** diff --git a/components/core/overlay/overlay-position.ts b/components/core/overlay/overlay-position.ts index 15b4d4a7d0e..577d23a7d21 100644 --- a/components/core/overlay/overlay-position.ts +++ b/components/core/overlay/overlay-position.ts @@ -28,6 +28,7 @@ export const POSITION_MAP: { [key: string]: ConnectionPositionPair } = { export const DEFAULT_TOOLTIP_POSITIONS = [POSITION_MAP.top, POSITION_MAP.right, POSITION_MAP.bottom, POSITION_MAP.left]; export const DEFAULT_DROPDOWN_POSITIONS = [POSITION_MAP.bottomLeft, POSITION_MAP.bottomRight, POSITION_MAP.topRight, POSITION_MAP.topLeft]; export const DEFAULT_SUBMENU_POSITIONS = [POSITION_MAP.rightTop, POSITION_MAP.leftTop]; +export const DEFAULT_CASCADER_POSITIONS = [POSITION_MAP.bottomLeft, POSITION_MAP.topLeft]; export const DEFAULT_MENTION_TOP_POSITIONS = [ new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'bottom' }),