diff --git a/components/date-picker/date-picker.component.spec.ts b/components/date-picker/date-picker.component.spec.ts index d2396a09fa..110010112c 100644 --- a/components/date-picker/date-picker.component.spec.ts +++ b/components/date-picker/date-picker.component.spec.ts @@ -221,6 +221,28 @@ describe('NzDatePickerComponent', () => { expect(getPickerContainer()).not.toBeNull(); })); + it('should prevent default on the mousedown event when mouse down in date picker', fakeAsync(() => { + fixture.detectChanges(); + openPickerByClickTrigger(); + + const event = new MouseEvent('mousedown'); + spyOn(event, 'preventDefault').and.callThrough(); + fixture.nativeElement.querySelector(`.${PREFIX_CLASS}`).dispatchEvent(event); + + expect(event.preventDefault).toHaveBeenCalled(); + })); + + it('should execute default on the mousedown event when mouse down in date picker input', fakeAsync(() => { + fixture.detectChanges(); + openPickerByClickTrigger(); + + const event = new MouseEvent('mousedown'); + spyOn(event, 'preventDefault').and.callThrough(); + fixture.nativeElement.querySelector(`.${PREFIX_CLASS} input`).dispatchEvent(event); + + expect(event.preventDefault).not.toHaveBeenCalled(); + })); + it('should support nzAllowClear and work properly', fakeAsync(() => { const clearBtnSelector = By.css(`.${PREFIX_CLASS}-clear`); const initial = (fixtureInstance.nzValue = new Date()); diff --git a/components/date-picker/date-picker.component.ts b/components/date-picker/date-picker.component.ts index 6098f9a19e..c32f895c2a 100644 --- a/components/date-picker/date-picker.component.ts +++ b/components/date-picker/date-picker.component.ts @@ -369,6 +369,10 @@ export class NzDatePickerComponent implements OnInit, OnChanges, OnDestroy, Afte this.focus(); this.updateInputWidthAndArrowLeft(); }); + + // prevent mousedown event to trigger focusout event when click in date picker + // see: https://github.com/NG-ZORRO/ng-zorro-antd/issues/7450 + this.elementRef.nativeElement.addEventListener('mousedown', this.onMouseDown); } updateInputWidthAndArrowLeft(): void { @@ -407,6 +411,12 @@ export class NzDatePickerComponent implements OnInit, OnChanges, OnDestroy, Afte } } + onMouseDown(event: Event): void { + if ((event.target as HTMLInputElement).tagName.toLowerCase() !== 'input') { + event.preventDefault(); + } + } + onFocus(event: FocusEvent, partType?: RangePartType): void { event.preventDefault(); if (partType) { @@ -697,6 +707,7 @@ export class NzDatePickerComponent implements OnInit, OnChanges, OnDestroy, Afte ngOnDestroy(): void { this.destroyed$.next(); this.destroyed$.complete(); + this.elementRef.nativeElement.removeEventListener('mousedown', this.onMouseDown); } setModeAndFormat(): void { diff --git a/components/date-picker/range-picker.component.spec.ts b/components/date-picker/range-picker.component.spec.ts index 583f5c25d0..18f8498a1d 100644 --- a/components/date-picker/range-picker.component.spec.ts +++ b/components/date-picker/range-picker.component.spec.ts @@ -140,6 +140,17 @@ describe('NzRangePickerComponent', () => { expect(getPickerContainer()).not.toBeNull(); })); + it('should execute default on the mousedown event when mouse down in date picker input', fakeAsync(() => { + fixture.detectChanges(); + openPickerByClickTrigger(); + + const event = new MouseEvent('mousedown'); + spyOn(event, 'preventDefault').and.callThrough(); + fixture.nativeElement.querySelector(`.${PREFIX_CLASS}-separator`).dispatchEvent(event); + + expect(event.preventDefault).not.toHaveBeenCalled(); + })); + it('should support nzAllowClear and work properly', fakeAsync(() => { const clearBtnSelector = By.css(`.${PREFIX_CLASS}-clear`); const initial = (fixtureInstance.modelValue = [new Date(), new Date()]);