diff --git a/components/auto-complete/autocomplete-trigger.directive.ts b/components/auto-complete/autocomplete-trigger.directive.ts index 0bb0014babb..51b19a5d165 100644 --- a/components/auto-complete/autocomplete-trigger.directive.ts +++ b/components/auto-complete/autocomplete-trigger.directive.ts @@ -19,8 +19,8 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { NzSafeAny, OnChangeType, OnTouchedType } from 'ng-zorro-antd/core/types'; import { NzInputGroupWhitSuffixOrPrefixDirective } from 'ng-zorro-antd/input'; -import { fromEvent, merge, Subject, Subscription } from 'rxjs'; -import { delay, takeUntil, tap } from 'rxjs/operators'; +import { merge, Subscription } from 'rxjs'; +import { delay, filter, tap } from 'rxjs/operators'; import { NzAutocompleteOptionComponent } from './autocomplete-option.component'; import { NzAutocompleteComponent } from './autocomplete.component'; @@ -67,14 +67,13 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD } } - private destroy$ = new Subject(); private overlayRef: OverlayRef | null = null; private portal: TemplatePortal<{}> | null = null; private positionStrategy!: FlexibleConnectedPositionStrategy; private previousValue: string | number | null = null; private selectionChangeSubscription!: Subscription; private optionsChangeSubscription!: Subscription; - private overlayBackdropClickSubscription!: Subscription; + private overlayOutsideClickSubscription!: Subscription; constructor( private elementRef: ElementRef, @@ -118,7 +117,7 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD if (this.overlayRef && this.overlayRef.hasAttached()) { this.selectionChangeSubscription.unsubscribe(); - this.overlayBackdropClickSubscription.unsubscribe(); + this.overlayOutsideClickSubscription.unsubscribe(); this.optionsChangeSubscription.unsubscribe(); this.overlayRef.dispose(); this.overlayRef = null; @@ -214,21 +213,11 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD }); } - /** - * Subscription external click and close panel - */ - private subscribeOverlayBackdropClick(): Subscription { - return merge( - fromEvent(this.document, 'click'), - fromEvent(this.document, 'touchend') - ).subscribe((event: MouseEvent | TouchEvent) => { - const clickTarget = event.target as HTMLElement; - - // Make sure is not self - if (clickTarget !== this.elementRef.nativeElement && !this.overlayRef!.overlayElement.contains(clickTarget) && this.panelOpen) { - this.closePanel(); - } - }); + private subscribeOverlayOutsideClick(): Subscription { + return merge( + this.overlayRef!.outsidePointerEvents().pipe(filter((e: MouseEvent) => !this.elementRef.nativeElement.contains(e.target))), + this.overlayRef!.detachments() + ).subscribe(() => this.closePanel()); } private attachOverlay(): void { @@ -247,14 +236,8 @@ export class NzAutocompleteTriggerDirective implements ControlValueAccessor, OnD if (this.overlayRef && !this.overlayRef.hasAttached()) { this.overlayRef.attach(this.portal); this.selectionChangeSubscription = this.subscribeSelectionChange(); - this.overlayBackdropClickSubscription = this.subscribeOverlayBackdropClick(); this.optionsChangeSubscription = this.subscribeOptionsChange(); - this.overlayRef - .detachments() - .pipe(takeUntil(this.destroy$)) - .subscribe(() => { - this.closePanel(); - }); + this.overlayOutsideClickSubscription = this.subscribeOverlayOutsideClick(); } this.nzAutocomplete.isOpen = this.panelOpen = true; } diff --git a/components/auto-complete/autocomplete.spec.ts b/components/auto-complete/autocomplete.spec.ts index 23135ec2d64..e2804bb4a02 100644 --- a/components/auto-complete/autocomplete.spec.ts +++ b/components/auto-complete/autocomplete.spec.ts @@ -154,7 +154,7 @@ describe('auto-complete', () => { expect(fixture.componentInstance.trigger.panelOpen).toBe(true); - dispatchFakeEvent(document, 'click'); + dispatchFakeEvent(document.body, 'click'); expect(fixture.componentInstance.trigger.panelOpen).toBe(false); })); diff --git a/components/cascader/cascader.component.ts b/components/cascader/cascader.component.ts index f09521435a1..fd24bb19226 100644 --- a/components/cascader/cascader.component.ts +++ b/components/cascader/cascader.component.ts @@ -111,13 +111,12 @@ const defaultDisplayRender = (labels: string[]) => labels.join(' / ');
{ openPickerByClickTrigger(); expect(getPickerContainer()).not.toBeNull(); - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); tick(500); fixture.detectChanges(); @@ -92,7 +92,7 @@ describe('NzDatePickerComponent', () => { fixture.detectChanges(); openPickerByClickTrigger(); - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); tick(500); fixture.detectChanges(); @@ -242,7 +242,6 @@ describe('NzDatePickerComponent', () => { tick(500); fixture.detectChanges(); expect(getPickerContainer()).not.toBeNull(); - expect(queryFromOverlay('.cdk-overlay-backdrop')).toBeNull(); fixtureInstance.nzOpen = false; fixture.detectChanges(); @@ -362,7 +361,7 @@ describe('NzDatePickerComponent', () => { openPickerByClickTrigger(); expect(nzOnOpenChange).toHaveBeenCalledWith(true); - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); flush(); expect(nzOnOpenChange).toHaveBeenCalledWith(false); @@ -776,7 +775,7 @@ describe('NzDatePickerComponent', () => { fixture.detectChanges(); expect(getPickerContainer()).not.toBeNull(); - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); tick(500); fixture.detectChanges(); diff --git a/components/date-picker/month-picker.component.spec.ts b/components/date-picker/month-picker.component.spec.ts index 1025c4ba326..71cf80805bd 100644 --- a/components/date-picker/month-picker.component.spec.ts +++ b/components/date-picker/month-picker.component.spec.ts @@ -56,7 +56,7 @@ describe('NzMonthPickerComponent', () => { openPickerByClickTrigger(); expect(getPickerContainer()).not.toBeNull(); - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); tick(500); fixture.detectChanges(); @@ -127,7 +127,6 @@ describe('NzMonthPickerComponent', () => { tick(500); fixture.detectChanges(); expect(getPickerContainer()).not.toBeNull(); - expect(queryFromOverlay('.cdk-overlay-backdrop')).toBeNull(); fixtureInstance.nzOpen = false; fixture.detectChanges(); @@ -206,7 +205,7 @@ describe('NzMonthPickerComponent', () => { openPickerByClickTrigger(); expect(nzOnOpenChange).toHaveBeenCalledWith(true); - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); flush(); expect(nzOnOpenChange).toHaveBeenCalledWith(false); diff --git a/components/date-picker/picker.component.ts b/components/date-picker/picker.component.ts index 02b1ccb8363..82e8199b100 100644 --- a/components/date-picker/picker.component.ts +++ b/components/date-picker/picker.component.ts @@ -130,13 +130,12 @@ import { PREFIX_CLASS } from './util'; nzConnectedOverlay [cdkConnectedOverlayOrigin]="origin" [cdkConnectedOverlayOpen]="realOpenState" - [cdkConnectedOverlayHasBackdrop]="!isOpenHandledByUser()" [cdkConnectedOverlayPositions]="overlayPositions" [cdkConnectedOverlayTransformOriginOn]="'.ant-picker-wrapper'" (positionChange)="onPositionChange($event)" - (backdropClick)="onClickBackdrop()" (detach)="onOverlayDetach()" (overlayKeydown)="onOverlayKeydown($event)" + (overlayOutsideClick)="onClickOutside($event)" >
{ openPickerByClickTrigger(); expect(getPickerContainer()).not.toBeNull(); - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); tick(500); fixture.detectChanges(); @@ -71,7 +71,7 @@ describe('NzRangePickerComponent', () => { fixture.detectChanges(); openPickerByClickTrigger(); - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); tick(500); fixture.detectChanges(); @@ -151,7 +151,6 @@ describe('NzRangePickerComponent', () => { tick(500); fixture.detectChanges(); expect(getPickerContainer()).not.toBeNull(); - expect(queryFromOverlay('.cdk-overlay-backdrop')).toBeNull(); fixtureInstance.nzOpen = false; fixture.detectChanges(); @@ -217,7 +216,7 @@ describe('NzRangePickerComponent', () => { openPickerByClickTrigger(); expect(nzOnOpenChange).toHaveBeenCalledWith(true); - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); tick(500); fixture.detectChanges(); @@ -356,7 +355,7 @@ describe('NzRangePickerComponent', () => { dispatchMouseEvent(getSuperNextBtn('left'), 'click'); fixture.detectChanges(); - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); tick(500); fixture.detectChanges(); @@ -430,7 +429,7 @@ describe('NzRangePickerComponent', () => { fixture.detectChanges(); expect(getRangePickerRightInput(fixture.debugElement) === document.activeElement).toBeTruthy(); - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); tick(500); fixture.detectChanges(); @@ -511,7 +510,7 @@ describe('NzRangePickerComponent', () => { ).toBeTruthy(); // Close left panel - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); tick(500); fixture.detectChanges(); @@ -537,7 +536,7 @@ describe('NzRangePickerComponent', () => { fixture.detectChanges(); // Close left panel - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); tick(500); fixture.detectChanges(); @@ -548,7 +547,7 @@ describe('NzRangePickerComponent', () => { expect(+queryFromOverlay('.ant-picker-time-panel-column:nth-child(3) li:first-child').textContent!.trim()).toBe(1); // Close left panel - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); tick(500); fixture.detectChanges(); @@ -767,7 +766,6 @@ describe('NzRangePickerComponent', () => { fixture.detectChanges(); flush(); fixture.detectChanges(); - expect(overlayContainerElement.querySelector('.cdk-overlay-backdrop')).toBeNull(); // TODO: input value should not be change // expect(leftInput.value).toBe('2018-09-11'); })); diff --git a/components/date-picker/year-picker.component.spec.ts b/components/date-picker/year-picker.component.spec.ts index b11b9111226..beba82fdd87 100644 --- a/components/date-picker/year-picker.component.spec.ts +++ b/components/date-picker/year-picker.component.spec.ts @@ -51,7 +51,7 @@ describe('NzYearPickerComponent', () => { openPickerByClickTrigger(); expect(getPickerContainer()).not.toBeNull(); - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); tick(500); fixture.detectChanges(); @@ -122,9 +122,6 @@ describe('NzYearPickerComponent', () => { tick(500); fixture.detectChanges(); expect(getPickerContainer()).not.toBeNull(); - expect(queryFromOverlay('.cdk-overlay-backdrop')).toBeNull(); - // dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); - // expect(getPickerContainer()).not.toBeNull(); fixtureInstance.nzOpen = false; fixture.detectChanges(); @@ -200,7 +197,7 @@ describe('NzYearPickerComponent', () => { openPickerByClickTrigger(); expect(nzOnOpenChange).toHaveBeenCalledWith(true); - dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + dispatchMouseEvent(document.body, 'click'); fixture.detectChanges(); flush(); expect(nzOnOpenChange).toHaveBeenCalledWith(false); diff --git a/components/dropdown/doc/index.en-US.md b/components/dropdown/doc/index.en-US.md index a0bd28026ba..7d2d22f2394 100755 --- a/components/dropdown/doc/index.en-US.md +++ b/components/dropdown/doc/index.en-US.md @@ -27,7 +27,6 @@ import { NzDropDownModule } from 'ng-zorro-antd/dropdown'; | `[nzTrigger]` | the trigger mode which executes the drop-down action | `'click' \| 'hover'` | `'hover'` | | `[nzClickHide]` | whether hide menu when click | `boolean` | `true` | | `[nzVisible]` | whether the dropdown menu is visible, double binding | `boolean` | - | -| `[nzBackdrop]` | whether the dropdown has a backdrop when `nzTrigger` is `click` | `boolean` | `true` | | `[nzOverlayClassName]` | Class name of the dropdown root element | `string` | - | | `[nzOverlayStyle]` | Style of the dropdown root element | `object` | - | | `(nzVisibleChange)` | a callback function takes an argument: `nzVisible`, is executed when the visible state is changed | `EventEmitter` | - | diff --git a/components/dropdown/doc/index.zh-CN.md b/components/dropdown/doc/index.zh-CN.md index 7b10498e6b3..d527e58f35b 100755 --- a/components/dropdown/doc/index.zh-CN.md +++ b/components/dropdown/doc/index.zh-CN.md @@ -28,7 +28,6 @@ import { NzDropDownModule } from 'ng-zorro-antd/dropdown'; | `[nzTrigger]` | 触发下拉的行为 | `'click' \| 'hover'` | `'hover'` | | `[nzClickHide]` | 点击后是否隐藏菜单 | `boolean` | `true` | | `[nzVisible]` | 菜单是否显示,可双向绑定 | `boolean` | - | -| `[nzBackdrop]` | 是否在 `nzTrigger` 为 `click`时增加背景蒙版 | `boolean` | `true` | | `[nzOverlayClassName]` | 下拉根元素的类名称 | `string` | - | | `[nzOverlayStyle]` | 下拉根元素的样式 | `object` | - | | `(nzVisibleChange)` | 菜单显示状态改变时调用,参数为 nzVisible | `EventEmitter` | - | diff --git a/components/dropdown/dropdown.directive.ts b/components/dropdown/dropdown.directive.ts index e35bd6741c5..f2550919828 100644 --- a/components/dropdown/dropdown.directive.ts +++ b/components/dropdown/dropdown.directive.ts @@ -21,6 +21,7 @@ import { SimpleChanges, ViewContainerRef } from '@angular/core'; +import { warnDeprecation } from 'ng-zorro-antd/core/logger'; import { POSITION_MAP } from 'ng-zorro-antd/core/overlay'; import { BooleanInput, IndexableObject } from 'ng-zorro-antd/core/types'; import { InputBoolean } from 'ng-zorro-antd/core/util'; @@ -57,6 +58,10 @@ export class NzDropDownDirective implements AfterViewInit, OnDestroy, OnChanges, @Input() nzDropdownMenu: NzDropdownMenuComponent | null = null; @Input() nzTrigger: 'click' | 'hover' = 'hover'; @Input() nzMatchWidthElement: ElementRef | null = null; + /** + * @deprecated Not supported. + * @breaking-change 11.0.0 + */ @Input() @InputBoolean() nzBackdrop = true; @Input() @InputBoolean() nzClickHide = true; @Input() @InputBoolean() nzDisabled = false; @@ -154,7 +159,6 @@ export class NzDropDownDirective implements AfterViewInit, OnDestroy, OnChanges, /** update overlay config **/ const overlayConfig = this.overlayRef.getConfig(); overlayConfig.minWidth = triggerWidth; - overlayConfig.hasBackdrop = this.nzTrigger === 'click'; } /** open dropdown with animation **/ this.positionStrategy.withPositions([POSITION_MAP[this.nzPlacement], ...listOfPositions]); @@ -183,7 +187,7 @@ export class NzDropDownDirective implements AfterViewInit, OnDestroy, OnChanges, } ngOnChanges(changes: SimpleChanges): void { - const { nzVisible, nzDisabled, nzOverlayClassName, nzOverlayStyle, nzTrigger } = changes; + const { nzVisible, nzDisabled, nzOverlayClassName, nzOverlayStyle, nzTrigger, nzBackdrop } = changes; if (nzTrigger) { this.nzTrigger$.next(this.nzTrigger); } @@ -205,5 +209,8 @@ export class NzDropDownDirective implements AfterViewInit, OnDestroy, OnChanges, if (nzOverlayStyle) { this.setDropdownMenuValue('nzOverlayStyle', this.nzOverlayStyle); } + if (nzBackdrop) { + warnDeprecation('`nzBackdrop` in dropdown component will be removed in 11.0.0.'); + } } } diff --git a/components/mention/mention.component.ts b/components/mention/mention.component.ts index cabe4a47c55..776ea7912a6 100644 --- a/components/mention/mention.component.ts +++ b/components/mention/mention.component.ts @@ -13,8 +13,8 @@ import { PositionStrategy } from '@angular/cdk/overlay'; import { TemplatePortal } from '@angular/cdk/portal'; - import { DOCUMENT } from '@angular/common'; + import { ChangeDetectionStrategy, ChangeDetectorRef, @@ -36,8 +36,8 @@ import { import { DEFAULT_MENTION_BOTTOM_POSITIONS, DEFAULT_MENTION_TOP_POSITIONS } from 'ng-zorro-antd/core/overlay'; import { BooleanInput, NzSafeAny } from 'ng-zorro-antd/core/types'; import { getCaretCoordinates, getMentions, InputBoolean } from 'ng-zorro-antd/core/util'; - import { fromEvent, merge, Subscription } from 'rxjs'; + import { NzMentionSuggestionDirective } from './mention-suggestions'; import { NzMentionTriggerDirective } from './mention-trigger'; import { NzMentionService } from './mention.service'; @@ -119,7 +119,7 @@ export class NzMentionComponent implements OnDestroy, OnInit, OnChanges { private overlayRef: OverlayRef | null = null; private portal?: TemplatePortal; private positionStrategy!: FlexibleConnectedPositionStrategy; - private overlayBackdropClickSubscription!: Subscription; + private overlayOutsideClickSubscription!: Subscription; private get triggerNativeElement(): HTMLTextAreaElement | HTMLInputElement { return this.trigger.el.nativeElement; @@ -159,7 +159,7 @@ export class NzMentionComponent implements OnDestroy, OnInit, OnChanges { closeDropdown(): void { if (this.overlayRef && this.overlayRef.hasAttached()) { this.overlayRef.detach(); - this.overlayBackdropClickSubscription.unsubscribe(); + this.overlayOutsideClickSubscription.unsubscribe(); this.isOpen = false; this.cdr.markForCheck(); } @@ -323,18 +323,13 @@ export class NzMentionComponent implements OnDestroy, OnInit, OnChanges { this.positionStrategy.apply(); } - private subscribeOverlayBackdropClick(): Subscription { + private subscribeOverlayOutsideClick(): Subscription { return merge( - fromEvent(this.ngDocument, 'click'), + this.overlayRef!.outsidePointerEvents(), fromEvent(this.ngDocument, 'touchend') ).subscribe((event: MouseEvent | TouchEvent) => { const clickTarget = event.target as HTMLElement; - if ( - this.isOpen && - clickTarget !== this.trigger.el.nativeElement && - !!this.overlayRef && - !this.overlayRef.overlayElement.contains(clickTarget) - ) { + if (this.isOpen && clickTarget !== this.trigger.el.nativeElement && !this.overlayRef?.overlayElement.contains(clickTarget)) { this.closeDropdown(); } }); @@ -347,7 +342,7 @@ export class NzMentionComponent implements OnDestroy, OnInit, OnChanges { } if (this.overlayRef && !this.overlayRef.hasAttached()) { this.overlayRef.attach(this.portal); - this.overlayBackdropClickSubscription = this.subscribeOverlayBackdropClick(); + this.overlayOutsideClickSubscription = this.subscribeOverlayOutsideClick(); } this.updatePositions(); } diff --git a/components/mention/nz-mention.spec.ts b/components/mention/nz-mention.spec.ts index fec54c8e1b1..b92ad56f95d 100644 --- a/components/mention/nz-mention.spec.ts +++ b/components/mention/nz-mention.spec.ts @@ -113,7 +113,7 @@ describe('mention', () => { fixture.detectChanges(); flush(); expect(mention.isOpen).toBe(true); - dispatchFakeEvent(document, 'click'); + dispatchFakeEvent(document.body, 'click'); expect(mention.isOpen).toBe(false); })); diff --git a/components/popconfirm/popconfirm.ts b/components/popconfirm/popconfirm.ts index 0586ea84a7d..67991b466a2 100644 --- a/components/popconfirm/popconfirm.ts +++ b/components/popconfirm/popconfirm.ts @@ -119,8 +119,7 @@ export class NzPopconfirmDirective extends NzTooltipBaseDirective { cdkConnectedOverlay nzConnectedOverlay [cdkConnectedOverlayOrigin]="origin" - [cdkConnectedOverlayHasBackdrop]="_hasBackdrop" - (backdropClick)="hide()" + (overlayOutsideClick)="onClickOutside($event)" (detach)="hide()" (positionChange)="onPositionChange($event)" [cdkConnectedOverlayPositions]="_positions" @@ -180,7 +179,6 @@ export class NzPopconfirmComponent extends NzToolTipComponent implements OnDestr protected _trigger: NzTooltipTrigger = 'click'; _prefix = 'ant-popover-placement'; - _hasBackdrop = true; constructor(cdr: ChangeDetectorRef, @Host() @Optional() public noAnimation?: NzNoAnimationDirective) { super(cdr, noAnimation); diff --git a/components/popover/popover.ts b/components/popover/popover.ts index 517ac0dbae7..9eb9dcdb44b 100644 --- a/components/popover/popover.ts +++ b/components/popover/popover.ts @@ -75,13 +75,12 @@ export class NzPopoverDirective extends NzTooltipBaseDirective { cdkConnectedOverlay nzConnectedOverlay [cdkConnectedOverlayOrigin]="origin" - [cdkConnectedOverlayHasBackdrop]="_hasBackdrop" - (backdropClick)="hide()" - (detach)="hide()" - (positionChange)="onPositionChange($event)" [cdkConnectedOverlayPositions]="_positions" [cdkConnectedOverlayOpen]="_visible" [cdkConnectedOverlayPush]="true" + (overlayOutsideClick)="onClickOutside($event)" + (detach)="hide()" + (positionChange)="onPositionChange($event)" >
{ expect(component.openChange).toHaveBeenCalledTimes(2); expect(component.openChange).toHaveBeenCalledWith(true); }); + it('should click input not close in searching mode', () => { + component.nzShowSearch = true; + fixture.detectChanges(); + const topSelectElement = selectElement.querySelector('.ant-select-selector')!; + dispatchFakeEvent(topSelectElement, 'click'); + fixture.detectChanges(); + expect(component.openChange).toHaveBeenCalledTimes(1); + expect(component.openChange).toHaveBeenCalledWith(true); + dispatchFakeEvent(topSelectElement, 'click'); + fixture.detectChanges(); + expect(component.openChange).toHaveBeenCalledTimes(1); + }); it('should nzCustomTemplate works', fakeAsync(() => { component.listOfOption = [{ nzValue: 'value', nzLabel: 'label' }]; fixture.detectChanges(); @@ -384,7 +396,7 @@ describe('select', () => { flushChanges(); expect(document.querySelectorAll('nz-option-item.ant-select-item-option-selected').length).toBe(1); expect(document.querySelectorAll('nz-option-item.ant-select-item-option-selected')[0].textContent).toBe('Truthy value'); - ['disabled', undefined, null].forEach((value) => { + ['disabled', undefined, null].forEach(value => { component.value = value; flushChanges(); expect(document.querySelectorAll('nz-option-item.ant-select-item-option-selected').length).toBe(0); @@ -633,7 +645,7 @@ describe('select', () => { expect(listOfItem[2].querySelector('.ant-select-selection-item-content')!.textContent).toBe('+ 2 ...'); component.nzMaxTagPlaceholder = component.tagTemplate; fixture.detectChanges(); - expect(listOfItem[2].textContent).toBe(' and 2 more selected '); + expect(listOfItem[2].textContent).toBe('and 2 more selected'); })); }); describe('default reactive mode', () => { @@ -1113,7 +1125,7 @@ describe('select', () => { expect(listOfItem[2].querySelector('.ant-select-selection-item-content')!.textContent).toBe('+ 2 ...'); component.nzMaxTagPlaceholder = component.tagTemplate; fixture.detectChanges(); - expect(listOfItem[2].textContent).toBe(' and 2 more selected '); + expect(listOfItem[2].textContent).toBe('and 2 more selected'); })); }); }); @@ -1263,7 +1275,7 @@ export class TestSelectTemplateMultipleComponent { [nzHide]="o.nzHide" > - and {{ selectedList.length }} more selected + and {{ selectedList.length }} more selected ` }) export class TestSelectTemplateTagsComponent { @@ -1360,8 +1372,7 @@ export class TestSelectReactiveDefaultComponent { [(nzOpen)]="nzOpen" (ngModelChange)="valueChange($event)" (nzOpenChange)="valueChange($event)" - > - + > icon ` }) @@ -1391,9 +1402,8 @@ export class TestSelectReactiveMultipleComponent { [nzTokenSeparators]="nzTokenSeparators" [nzMaxTagPlaceholder]="nzMaxTagPlaceholder" (ngModelChange)="valueChange($event)" - > - - and {{ selectedList.length }} more selected + > + and {{ selectedList.length }} more selected ` }) export class TestSelectReactiveTagsComponent { diff --git a/components/time-picker/time-picker.component.ts b/components/time-picker/time-picker.component.ts index cc6f803869c..5ee302cf799 100644 --- a/components/time-picker/time-picker.component.ts +++ b/components/time-picker/time-picker.component.ts @@ -67,14 +67,13 @@ const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'timePicker';
@@ -219,6 +218,12 @@ export class NzTimePickerComponent implements ControlValueAccessor, OnInit, Afte this.emitValue(null); } + onClickOutside(event: MouseEvent): void { + if (!this.element.nativeElement.contains(event.target)) { + this.setCurrentValueAndClose(); + } + } + onFocus(value: boolean): void { this.focused = value; } diff --git a/components/tooltip/base.ts b/components/tooltip/base.ts index 46d877eba0f..4d2187a490b 100644 --- a/components/tooltip/base.ts +++ b/components/tooltip/base.ts @@ -328,7 +328,6 @@ export abstract class NzTooltipBaseComponent implements OnDestroy { set nzTrigger(value: NzTooltipTrigger) { this._trigger = value; - this._hasBackdrop = this._trigger === 'click'; } get nzTrigger(): NzTooltipTrigger { @@ -352,7 +351,6 @@ export abstract class NzTooltipBaseComponent implements OnDestroy { preferredPlacement = 'top'; _classMap: NgClassInterface = {}; - _hasBackdrop = false; _prefix = 'ant-tooltip-placement'; _positions: ConnectionPositionPair[] = [...DEFAULT_TOOLTIP_POSITIONS]; @@ -421,6 +419,12 @@ export abstract class NzTooltipBaseComponent implements OnDestroy { this.cdr.markForCheck(); } + onClickOutside(event: MouseEvent): void { + if (!this.origin.elementRef.nativeElement.contains(event.target)) { + this.hide(); + } + } + /** * Hide the component while the content is empty. */ diff --git a/components/tooltip/tooltip.spec.ts b/components/tooltip/tooltip.spec.ts index 8da2aeb1999..18ac1244ca7 100644 --- a/components/tooltip/tooltip.spec.ts +++ b/components/tooltip/tooltip.spec.ts @@ -49,10 +49,6 @@ describe('nz-tooltip', () => { fixture.detectChanges(); } - function getTooltipBackdropElement(): HTMLElement { - return overlayContainerElement.querySelector('.cdk-overlay-backdrop') as HTMLElement; - } - beforeEach(() => { fixture = testBed.fixture; component = testBed.component; @@ -129,7 +125,7 @@ describe('nz-tooltip', () => { waitingForTooltipToggling(); expect(overlayContainerElement.textContent).toContain(title); - dispatchMouseEvent(getTooltipBackdropElement(), 'click'); + dispatchMouseEvent(document.body, 'click'); waitingForTooltipToggling(); expect(overlayContainerElement.textContent).not.toContain(title); })); @@ -251,7 +247,7 @@ describe('nz-tooltip', () => { waitingForTooltipToggling(); expect(overlayContainerElement.textContent).toContain(featureKey); - dispatchMouseEvent(getTooltipBackdropElement(), 'click'); + dispatchMouseEvent(document.body, 'click'); waitingForTooltipToggling(); expect(overlayContainerElement.textContent).not.toContain(featureKey); diff --git a/components/tooltip/tooltip.ts b/components/tooltip/tooltip.ts index a721ba5a74c..145178c0a2e 100644 --- a/components/tooltip/tooltip.ts +++ b/components/tooltip/tooltip.ts @@ -74,10 +74,9 @@ export class NzTooltipDirective extends NzTooltipBaseDirective { nzConnectedOverlay [cdkConnectedOverlayOrigin]="origin" [cdkConnectedOverlayOpen]="_visible" - [cdkConnectedOverlayHasBackdrop]="_hasBackdrop" [cdkConnectedOverlayPositions]="_positions" [cdkConnectedOverlayPush]="true" - (backdropClick)="hide()" + (overlayOutsideClick)="hide()" (detach)="hide()" (positionChange)="onPositionChange($event)" > diff --git a/components/tree-select/tree-select.component.ts b/components/tree-select/tree-select.component.ts index 8cfd3b795d1..efa12669711 100644 --- a/components/tree-select/tree-select.component.ts +++ b/components/tree-select/tree-select.component.ts @@ -66,11 +66,10 @@ const TREE_SELECT_DEFAULT_CLASS = 'ant-select-dropdown ant-select-tree-dropdown' nzConnectedOverlay [cdkConnectedOverlayOrigin]="cdkOverlayOrigin" [cdkConnectedOverlayOpen]="nzOpen" - [cdkConnectedOverlayHasBackdrop]="true" [cdkConnectedOverlayTransformOriginOn]="'.ant-select-tree-dropdown'" [cdkConnectedOverlayMinWidth]="$any(nzDropdownMatchSelectWidth ? null : triggerWidth)" [cdkConnectedOverlayWidth]="$any(nzDropdownMatchSelectWidth ? triggerWidth : null)" - (backdropClick)="closeDropDown()" + (overlayOutsideClick)="onClickOutside($event)" (detach)="closeDropDown()" (positionChange)="onPositionChange($event)" > @@ -518,6 +517,12 @@ export class NzTreeSelectComponent extends NzTreeBase implements ControlValueAcc this.nzCleared.emit(); } + onClickOutside(event: MouseEvent): void { + if (!this.elementRef.nativeElement.contains(event.target)) { + this.closeDropDown(); + } + } + setSearchValues($event: NzFormatEmitEvent): void { Promise.resolve().then(() => { this.isNotFound = (this.nzShowSearch || this.isMultiple) && !!this.inputValue && $event.matchedKeys!.length === 0; diff --git a/components/tree-select/tree-select.spec.ts b/components/tree-select/tree-select.spec.ts index b8aabd939a5..0b65d0b2375 100644 --- a/components/tree-select/tree-select.spec.ts +++ b/components/tree-select/tree-select.spec.ts @@ -103,7 +103,7 @@ describe('tree-select component', () => { treeSelect.nativeElement.click(); fixture.detectChanges(); expect(treeSelectComponent.nzOpen).toBe(true); - dispatchFakeEvent(overlayContainerElement.querySelector('.cdk-overlay-backdrop')!, 'click'); + dispatchFakeEvent(document.body, 'click'); fixture.detectChanges(); expect(treeSelectComponent.nzOpen).toBe(false); fixture.detectChanges();