Skip to content

Commit 5fec53e

Browse files
authored
fix(module:cascader): correct menu display level (#8866)
1 parent 30c25f0 commit 5fec53e

File tree

3 files changed

+65
-15
lines changed

3 files changed

+65
-15
lines changed

components/cascader/cascader.component.ts

+5
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,7 @@ export class NzCascaderComponent
734734
const options = this.cascaderService.activatedOptions;
735735
if (options.length) {
736736
options.pop(); // Remove the last one
737+
this.cascaderService.setOptionDeactivatedSinceColumn(options.length); // collapse menu
737738
}
738739
}
739740

@@ -790,6 +791,10 @@ export class NzCascaderComponent
790791
this.blur();
791792
this.clearDelayMenuTimer();
792793
this.setMenuVisible(false);
794+
// if select none, clear previous state
795+
if (!this.hasValue && this.cascaderService.columns.length) {
796+
this.cascaderService.dropBehindColumns(0);
797+
}
793798
}
794799

795800
/**

components/cascader/cascader.service.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,8 @@ export class NzCascaderService implements OnDestroy {
358358
if (!arraysEqual(existingOptions, options)) {
359359
options.forEach(o => (o.parent = parent));
360360
this.columns[columnIndex] = options;
361-
this.dropBehindColumns(columnIndex);
362361
}
362+
this.dropBehindColumns(columnIndex);
363363
}
364364

365365
/**
@@ -377,7 +377,7 @@ export class NzCascaderService implements OnDestroy {
377377
this.activatedOptions = this.activatedOptions.splice(0, lastReserveIndex + 1);
378378
}
379379

380-
private dropBehindColumns(lastReserveIndex: number): void {
380+
dropBehindColumns(lastReserveIndex: number): void {
381381
if (lastReserveIndex < this.columns.length - 1) {
382382
this.columns = this.columns.slice(0, lastReserveIndex + 1);
383383
}

components/cascader/cascader.spec.ts

+58-13
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { provideNoopAnimations } from '@angular/platform-browser/animations';
2727
import {
2828
createFakeEvent,
2929
createMouseEvent,
30+
dispatchFakeEvent,
3031
dispatchKeyboardEvent,
3132
dispatchMouseEvent
3233
} from 'ng-zorro-antd/core/testing';
@@ -741,9 +742,9 @@ describe('cascader', () => {
741742
expect(testComponent.cascader.menuVisible).toBe(true);
742743
expect(getAllColumns().length).toBe(3);
743744

744-
const itemEl1 = getItemAtColumnAndRow(1, 1)!;
745-
const itemEl2 = getItemAtColumnAndRow(2, 1)!;
746-
const itemEl3 = getItemAtColumnAndRow(3, 1)!;
745+
let itemEl1 = getItemAtColumnAndRow(1, 1)!;
746+
let itemEl2 = getItemAtColumnAndRow(2, 1)!;
747+
let itemEl3 = getItemAtColumnAndRow(3, 1)!;
747748

748749
expect(itemEl1.classList).toContain('ant-cascader-menu-item-active');
749750
expect(itemEl2.classList).toContain('ant-cascader-menu-item-active');
@@ -755,14 +756,17 @@ describe('cascader', () => {
755756
fixture.detectChanges();
756757
dispatchKeyboardEvent(cascader.nativeElement, 'keydown', LEFT_ARROW);
757758
fixture.detectChanges();
758-
expect(getAllColumns().length).toBe(3);
759+
itemEl1 = getItemAtColumnAndRow(1, 1)!;
760+
itemEl2 = getItemAtColumnAndRow(2, 1)!;
761+
itemEl3 = getItemAtColumnAndRow(3, 1)!;
759762
expect(itemEl1.classList).not.toContain('ant-cascader-menu-item-active');
760-
expect(itemEl2.classList).not.toContain('ant-cascader-menu-item-active');
761-
expect(itemEl3.classList).not.toContain('ant-cascader-menu-item-active');
763+
expect(itemEl2).toBeNull();
764+
expect(itemEl3).toBeNull();
765+
expect(getAllColumns().length).toBe(1);
762766
expect(testComponent.values!.join(',')).toBe('zhejiang,hangzhou,xihu');
763767

768+
itemEl1.click();
764769
const itemEl4 = getItemAtColumnAndRow(2, 2)!;
765-
766770
itemEl4.click(); // 选中一个叶子
767771
fixture.detectChanges();
768772
tick(300);
@@ -870,6 +874,44 @@ describe('cascader', () => {
870874
expect(testComponent.cascader.menuVisible).toBe(false);
871875
}));
872876

877+
it('should init menu when selecting cancel', fakeAsync(() => {
878+
// cancel select by ESCAPE
879+
fixture.detectChanges();
880+
testComponent.cascader.setMenuVisible(true);
881+
let itemEl1 = getItemAtColumnAndRow(1, 1)!;
882+
itemEl1.click();
883+
let itemEl2 = getItemAtColumnAndRow(2, 1)!;
884+
itemEl2.click();
885+
let itemEl3 = getItemAtColumnAndRow(3, 1)!;
886+
expect(itemEl1.classList).toContain('ant-cascader-menu-item-active');
887+
expect(itemEl2.classList).toContain('ant-cascader-menu-item-active');
888+
expect(itemEl3.classList).not.toContain('ant-cascader-menu-item-active');
889+
dispatchKeyboardEvent(cascader.nativeElement, 'keydown', ESCAPE);
890+
fixture.detectChanges();
891+
flush();
892+
fixture.detectChanges();
893+
expect(testComponent.cascader.menuVisible).toBe(false);
894+
expect(testComponent.cascader.cascaderService.columns.length).toBe(1);
895+
896+
// cancel select by clicking outside
897+
fixture.detectChanges();
898+
testComponent.cascader.setMenuVisible(true);
899+
itemEl1 = getItemAtColumnAndRow(1, 1)!;
900+
itemEl1.click();
901+
itemEl2 = getItemAtColumnAndRow(2, 1)!;
902+
itemEl2.click();
903+
itemEl3 = getItemAtColumnAndRow(3, 1)!;
904+
expect(itemEl1.classList).toContain('ant-cascader-menu-item-active');
905+
expect(itemEl2.classList).toContain('ant-cascader-menu-item-active');
906+
expect(itemEl3.classList).not.toContain('ant-cascader-menu-item-active');
907+
dispatchFakeEvent(document.body, 'click');
908+
fixture.detectChanges();
909+
flush();
910+
fixture.detectChanges();
911+
expect(testComponent.cascader.menuVisible).toBe(false);
912+
expect(testComponent.cascader.cascaderService.columns.length).toBe(1);
913+
}));
914+
873915
it('should nzBackdrop works', fakeAsync(() => {
874916
testComponent.nzBackdrop = true;
875917
fixture.detectChanges();
@@ -941,9 +983,9 @@ describe('cascader', () => {
941983
fixture.detectChanges();
942984
expect(getAllColumns().length).toBe(3);
943985

944-
const itemEl1 = getItemAtColumnAndRow(1, 1)!;
945-
const itemEl2 = getItemAtColumnAndRow(2, 1)!;
946-
const itemEl3 = getItemAtColumnAndRow(3, 1)!;
986+
let itemEl1 = getItemAtColumnAndRow(1, 1)!;
987+
let itemEl2 = getItemAtColumnAndRow(2, 1)!;
988+
let itemEl3 = getItemAtColumnAndRow(3, 1)!;
947989
expect(itemEl1.classList).toContain('ant-cascader-menu-item-active');
948990
expect(itemEl2.classList).toContain('ant-cascader-menu-item-active');
949991
expect(itemEl3.classList).toContain('ant-cascader-menu-item-active');
@@ -954,14 +996,17 @@ describe('cascader', () => {
954996
expect(itemEl3.classList).not.toContain('ant-cascader-menu-item-active');
955997
dispatchKeyboardEvent(cascader.nativeElement, 'keydown', LEFT_ARROW);
956998
fixture.detectChanges();
999+
itemEl3 = getItemAtColumnAndRow(3, 1)!;
9571000
expect(itemEl1.classList).toContain('ant-cascader-menu-item-active');
9581001
expect(itemEl2.classList).not.toContain('ant-cascader-menu-item-active');
959-
expect(itemEl3.classList).not.toContain('ant-cascader-menu-item-active');
1002+
expect(itemEl3).toBeNull();
1003+
expect(getAllColumns().length).toBe(2);
9601004
dispatchKeyboardEvent(cascader.nativeElement, 'keydown', LEFT_ARROW);
9611005
fixture.detectChanges();
1006+
itemEl2 = getItemAtColumnAndRow(2, 1)!;
9621007
expect(itemEl1.classList).not.toContain('ant-cascader-menu-item-active');
963-
expect(itemEl2.classList).not.toContain('ant-cascader-menu-item-active');
964-
expect(itemEl3.classList).not.toContain('ant-cascader-menu-item-active');
1008+
expect(itemEl2).toBeNull();
1009+
expect(getAllColumns().length).toBe(1);
9651010
}));
9661011

9671012
it('should select option when press ENTER', fakeAsync(() => {

0 commit comments

Comments
 (0)