diff --git a/components/date-picker/date-picker.component.spec.ts b/components/date-picker/date-picker.component.spec.ts
index 2f356ef7bb8..8b8380e97ee 100644
--- a/components/date-picker/date-picker.component.spec.ts
+++ b/components/date-picker/date-picker.component.spec.ts
@@ -13,7 +13,7 @@ import isSameDay from 'date-fns/isSameDay';
import { enUS } from 'date-fns/locale';
-import { dispatchKeyboardEvent, dispatchMouseEvent, typeInElement } from 'ng-zorro-antd/core/testing';
+import { dispatchFakeEvent, dispatchKeyboardEvent, dispatchMouseEvent, typeInElement } from 'ng-zorro-antd/core/testing';
import { NgStyleInterface } from 'ng-zorro-antd/core/types';
import { NzI18nModule, NzI18nService, NZ_DATE_LOCALE } from 'ng-zorro-antd/i18n';
import en_US from '../i18n/languages/en_US';
@@ -70,7 +70,7 @@ describe('NzDatePickerComponent', () => {
openPickerByClickTrigger();
expect(getPickerContainer()).not.toBeNull();
- dispatchMouseEvent(document.body, 'click');
+ triggerInputBlur();
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -96,7 +96,7 @@ describe('NzDatePickerComponent', () => {
fixture.detectChanges();
openPickerByClickTrigger();
- dispatchMouseEvent(document.body, 'click');
+ triggerInputBlur();
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -151,16 +151,23 @@ describe('NzDatePickerComponent', () => {
}));
it('should open by click and close by tab', fakeAsync(() => {
+ const nzOnChange = spyOn(fixtureInstance, 'nzOnChange');
fixtureInstance.useSuite = 5;
fixture.detectChanges();
openPickerByClickTrigger();
expect(getPickerContainer()).not.toBeNull();
- getSecondPickerInput(fixture.debugElement).focus();
+ typeInElement('2021-04-12', getPickerInput(fixture.debugElement));
fixture.detectChanges();
- flush();
+
+ triggerInputBlur();
+ fixture.detectChanges();
+ tick(500);
fixture.detectChanges();
+
+ const result = (nzOnChange.calls.allArgs()[0] as Date[])[0];
+ expect(isSameDay(new Date('2021-04-12'), result)).toBeTruthy();
expect(getPickerContainer()).toBeNull();
}));
@@ -379,7 +386,7 @@ describe('NzDatePickerComponent', () => {
openPickerByClickTrigger();
expect(nzOnOpenChange).toHaveBeenCalledWith(true);
- dispatchMouseEvent(document.body, 'click');
+ triggerInputBlur();
fixture.detectChanges();
flush();
expect(nzOnOpenChange).toHaveBeenCalledWith(false);
@@ -481,10 +488,6 @@ describe('NzDatePickerComponent', () => {
openPickerByClickTrigger();
expect(overlayContainerElement.children[0].classList).toContain('cdk-overlay-backdrop');
}));
-
- function getSecondPickerInput(fixtureDebugElement: DebugElement): HTMLInputElement {
- return fixtureDebugElement.queryAll(By.css(`.${PREFIX_CLASS}-input input`))[1].nativeElement as HTMLInputElement;
- }
});
describe('panel switch and move forward/afterward', () => {
@@ -826,7 +829,7 @@ describe('NzDatePickerComponent', () => {
fixture.detectChanges();
expect(getPickerContainer()).not.toBeNull();
- dispatchMouseEvent(document.body, 'click');
+ triggerInputBlur();
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -980,7 +983,7 @@ describe('NzDatePickerComponent', () => {
flush();
fixture.detectChanges();
- dispatchMouseEvent(document.body, 'click');
+ triggerInputBlur();
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -1067,6 +1070,10 @@ describe('NzDatePickerComponent', () => {
tick(500);
fixture.detectChanges();
}
+
+ function triggerInputBlur(): void {
+ dispatchFakeEvent(getPickerInput(fixture.debugElement), 'blur');
+ }
});
describe('date-fns testing', () => {
@@ -1162,7 +1169,7 @@ describe('date-fns testing', () => {
-
+
diff --git a/components/date-picker/date-picker.component.ts b/components/date-picker/date-picker.component.ts
index 6ae1b1da253..c831dd62918 100644
--- a/components/date-picker/date-picker.component.ts
+++ b/components/date-picker/date-picker.component.ts
@@ -78,6 +78,7 @@ export type NzDatePickerSizeType = 'large' | 'default' | 'small';
[nzId]="nzId"
>
| string;
dir: Direction = 'ltr';
@@ -383,16 +383,12 @@ export class NzDatePickerComponent implements OnInit, OnChanges, OnDestroy, Cont
this.datePickerService.initialValue = newValue;
}
- onFocusChange(value: FocusEvent): void {
- // When the relatedTarget is part of the elementRef, it means that it's a range-picker and you are navigating to
- // the other input in that range picker. In that case we don't want to close the picker.
- this.focused = (value.type === 'blur' && this.elementRef.nativeElement.contains(value.relatedTarget)) || value.type === 'focus';
+ onFocusChange(value: boolean): void {
// TODO: avoid autoFocus cause change after checked error
- if (this.focused) {
+ if (value) {
this.renderer.addClass(this.elementRef.nativeElement, 'ant-picker-focused');
} else {
this.renderer.removeClass(this.elementRef.nativeElement, 'ant-picker-focused');
- this.close();
}
}
diff --git a/components/date-picker/month-picker.component.spec.ts b/components/date-picker/month-picker.component.spec.ts
index 71cf80805bd..6a531acb72f 100644
--- a/components/date-picker/month-picker.component.spec.ts
+++ b/components/date-picker/month-picker.component.spec.ts
@@ -8,7 +8,7 @@ import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import isBefore from 'date-fns/isBefore';
-import { dispatchMouseEvent } from 'ng-zorro-antd/core/testing';
+import { dispatchFakeEvent, dispatchMouseEvent } from 'ng-zorro-antd/core/testing';
import { NgStyleInterface } from 'ng-zorro-antd/core/types';
import { getPickerAbstract, getPickerInput } from 'ng-zorro-antd/date-picker/testing/util';
import { PREFIX_CLASS } from 'ng-zorro-antd/date-picker/util';
@@ -56,7 +56,7 @@ describe('NzMonthPickerComponent', () => {
openPickerByClickTrigger();
expect(getPickerContainer()).not.toBeNull();
- dispatchMouseEvent(document.body, 'click');
+ dispatchFakeEvent(getPickerInput(fixture.debugElement), 'blur');
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -205,7 +205,7 @@ describe('NzMonthPickerComponent', () => {
openPickerByClickTrigger();
expect(nzOnOpenChange).toHaveBeenCalledWith(true);
- dispatchMouseEvent(document.body, 'click');
+ dispatchFakeEvent(getPickerInput(fixture.debugElement), 'blur');
fixture.detectChanges();
flush();
expect(nzOnOpenChange).toHaveBeenCalledWith(false);
diff --git a/components/date-picker/picker.component.ts b/components/date-picker/picker.component.ts
index f039c0032f5..5ced4f74c59 100644
--- a/components/date-picker/picker.component.ts
+++ b/components/date-picker/picker.component.ts
@@ -155,7 +155,6 @@ import { PREFIX_CLASS } from './util';
(positionChange)="onPositionChange($event)"
(detach)="onOverlayDetach()"
(overlayKeydown)="onOverlayKeydown($event)"
- (overlayOutsideClick)="onClickOutside($event)"
>
@@ -182,7 +181,7 @@ export class NzPickerComponent implements OnInit, AfterViewInit, OnChanges, OnDe
@Input() nzId: string | null = null;
@Input() hasBackdrop = false;
- @Output() readonly focusChange = new EventEmitter();
+ @Output() readonly focusChange = new EventEmitter();
@Output() readonly valueChange = new EventEmitter();
@Output() readonly openChange = new EventEmitter(); // Emitted when overlay's open state change
@@ -312,7 +311,6 @@ export class NzPickerComponent implements OnInit, AfterViewInit, OnChanges, OnDe
this.activeBarStyle = { ...baseStyle, left: `${this.datePickerService.arrowLeft}px` };
}
- this.panel.cdr.markForCheck();
this.cdr.markForCheck();
}
@@ -336,7 +334,7 @@ export class NzPickerComponent implements OnInit, AfterViewInit, OnChanges, OnDe
onFocus(event: FocusEvent, partType?: RangePartType): void {
event.preventDefault();
- this.focusChange.emit(event);
+ this.focusChange.emit(true);
if (partType) {
this.datePickerService.inputPartChange$.next(partType);
}
@@ -344,7 +342,12 @@ export class NzPickerComponent implements OnInit, AfterViewInit, OnChanges, OnDe
onBlur(event: FocusEvent): void {
event.preventDefault();
- this.focusChange.emit(event);
+ this.focusChange.emit(false);
+
+ const isFocus = this.elementRef.nativeElement.contains(event.relatedTarget);
+ if (!isFocus) {
+ this.checkAndClose();
+ }
}
// Show overlay content
@@ -356,7 +359,6 @@ export class NzPickerComponent implements OnInit, AfterViewInit, OnChanges, OnDe
this.updateInputWidthAndArrowLeft();
this.overlayOpen = true;
this.focus();
- this.panel.init();
this.openChange.emit(true);
this.cdr.markForCheck();
}
@@ -376,16 +378,8 @@ export class NzPickerComponent implements OnInit, AfterViewInit, OnChanges, OnDe
return !this.disabled && !this.isEmptyValue(this.datePickerService.value) && !!this.allowClear;
}
- onClickInputBox(event: MouseEvent): void {
- event.stopPropagation();
- this.focus();
- if (!this.isOpenHandledByUser()) {
- this.showOverlay();
- }
- }
-
- onClickOutside(event: MouseEvent): void {
- if (this.elementRef.nativeElement.contains(event.target)) {
+ checkAndClose(): void {
+ if (!this.realOpenState) {
return;
}
@@ -404,6 +398,14 @@ export class NzPickerComponent implements OnInit, AfterViewInit, OnChanges, OnDe
}
}
+ onClickInputBox(event: MouseEvent): void {
+ event.stopPropagation();
+ this.focus();
+ if (!this.isOpenHandledByUser()) {
+ this.showOverlay();
+ }
+ }
+
onOverlayDetach(): void {
this.hideOverlay();
}
diff --git a/components/date-picker/range-picker.component.spec.ts b/components/date-picker/range-picker.component.spec.ts
index 2cdf6c503f5..224de0f7479 100644
--- a/components/date-picker/range-picker.component.spec.ts
+++ b/components/date-picker/range-picker.component.spec.ts
@@ -60,7 +60,7 @@ describe('NzRangePickerComponent', () => {
openPickerByClickTrigger();
expect(getPickerContainer()).not.toBeNull();
- dispatchMouseEvent(document.body, 'click');
+ triggerInputBlur();
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -81,6 +81,7 @@ describe('NzRangePickerComponent', () => {
fixture.detectChanges();
expect(getPickerContainer()).not.toBeNull();
+ triggerInputBlur();
getRegularPickerInput(fixture.debugElement).focus();
fixture.detectChanges();
tick(500);
@@ -92,7 +93,7 @@ describe('NzRangePickerComponent', () => {
fixture.detectChanges();
openPickerByClickTrigger();
- dispatchMouseEvent(document.body, 'click');
+ triggerInputBlur();
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -237,7 +238,7 @@ describe('NzRangePickerComponent', () => {
openPickerByClickTrigger();
expect(nzOnOpenChange).toHaveBeenCalledWith(true);
- dispatchMouseEvent(document.body, 'click');
+ triggerInputBlur();
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -402,7 +403,7 @@ describe('NzRangePickerComponent', () => {
dispatchMouseEvent(getSuperNextBtn('left'), 'click');
fixture.detectChanges();
- dispatchMouseEvent(document.body, 'click');
+ triggerInputBlur();
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -476,7 +477,7 @@ describe('NzRangePickerComponent', () => {
fixture.detectChanges();
expect(getRangePickerRightInput(fixture.debugElement) === document.activeElement).toBeTruthy();
- dispatchMouseEvent(document.body, 'click');
+ triggerInputBlur();
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -557,7 +558,7 @@ describe('NzRangePickerComponent', () => {
).toBeTruthy();
// Close left panel
- dispatchMouseEvent(document.body, 'click');
+ triggerInputBlur();
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -583,7 +584,7 @@ describe('NzRangePickerComponent', () => {
fixture.detectChanges();
// Close left panel
- dispatchMouseEvent(document.body, 'click');
+ triggerInputBlur('right');
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -594,7 +595,7 @@ describe('NzRangePickerComponent', () => {
expect(+queryFromOverlay('.ant-picker-time-panel-column:nth-child(3) li:first-child').textContent!.trim()).toBe(1);
// Close left panel
- dispatchMouseEvent(document.body, 'click');
+ triggerInputBlur();
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -955,10 +956,6 @@ describe('NzRangePickerComponent', () => {
return fixtureDebugElement.queryAll(By.css(`.${PREFIX_CLASS}-input input`))[2].nativeElement as HTMLInputElement;
}
- // function getSecondSelectedDayCell(): HTMLElement {
- // return queryFromOverlay('.ant-picker-panel:last-child td.ant-picker-cell-selected .ant-picker-cell-inner') as HTMLElement;
- // }
-
function getPreBtn(part: RangePartType): HTMLElement {
return queryFromOverlay(`.ant-picker-panel:${getCssIndex(part)} .${PREFIX_CLASS}-header-prev-btn`);
}
@@ -1017,6 +1014,14 @@ describe('NzRangePickerComponent', () => {
tick(500);
fixture.detectChanges();
}
+
+ function triggerInputBlur(part: 'left' | 'right' = 'left'): void {
+ if (part === 'left') {
+ dispatchFakeEvent(getPickerInput(fixture.debugElement), 'blur');
+ } else {
+ dispatchFakeEvent(getRangePickerRightInput(fixture.debugElement), 'blur');
+ }
+ }
});
@Component({
diff --git a/components/date-picker/year-picker.component.spec.ts b/components/date-picker/year-picker.component.spec.ts
index beba82fdd87..141fe6dc262 100644
--- a/components/date-picker/year-picker.component.spec.ts
+++ b/components/date-picker/year-picker.component.spec.ts
@@ -5,7 +5,7 @@ import { FormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
-import { dispatchMouseEvent } from 'ng-zorro-antd/core/testing';
+import { dispatchFakeEvent, dispatchMouseEvent } from 'ng-zorro-antd/core/testing';
import { NgStyleInterface } from 'ng-zorro-antd/core/types';
import { getPickerAbstract, getPickerInput } from 'ng-zorro-antd/date-picker/testing/util';
import { PREFIX_CLASS } from 'ng-zorro-antd/date-picker/util';
@@ -51,7 +51,7 @@ describe('NzYearPickerComponent', () => {
openPickerByClickTrigger();
expect(getPickerContainer()).not.toBeNull();
- dispatchMouseEvent(document.body, 'click');
+ dispatchFakeEvent(getPickerInput(fixture.debugElement), 'blur');
fixture.detectChanges();
tick(500);
fixture.detectChanges();
@@ -197,7 +197,7 @@ describe('NzYearPickerComponent', () => {
openPickerByClickTrigger();
expect(nzOnOpenChange).toHaveBeenCalledWith(true);
- dispatchMouseEvent(document.body, 'click');
+ dispatchFakeEvent(getPickerInput(fixture.debugElement), 'blur');
fixture.detectChanges();
flush();
expect(nzOnOpenChange).toHaveBeenCalledWith(false);