diff --git a/src/lib/datepicker/calendar.spec.ts b/src/lib/datepicker/calendar.spec.ts index d5fe98145610..c4fb499e5505 100644 --- a/src/lib/datepicker/calendar.spec.ts +++ b/src/lib/datepicker/calendar.spec.ts @@ -20,9 +20,10 @@ import { JUL, JUN, MAR, - MAY, MatNativeDateModule, + MAY, NOV, + OCT, SEP, } from '@angular/material/core'; import {By} from '@angular/platform-browser'; @@ -341,7 +342,7 @@ describe('MatCalendar', () => { dispatchKeyboardEvent(calendarBodyEl, 'keydown', UP_ARROW); fixture.detectChanges(); - expect(calendarInstance._activeDate).toEqual(new Date(2016, AUG, 31)); + expect(calendarInstance._activeDate).toEqual(new Date(2016, SEP, 30)); calendarInstance._activeDate = new Date(2017, JUL, 1); fixture.detectChanges(); @@ -349,7 +350,7 @@ describe('MatCalendar', () => { dispatchKeyboardEvent(calendarBodyEl, 'keydown', UP_ARROW); fixture.detectChanges(); - expect(calendarInstance._activeDate).toEqual(new Date(2016, JUL, 1)); + expect(calendarInstance._activeDate).toEqual(new Date(2017, MAR, 1)); calendarInstance._activeDate = new Date(2017, DEC, 10); fixture.detectChanges(); @@ -357,14 +358,14 @@ describe('MatCalendar', () => { dispatchKeyboardEvent(calendarBodyEl, 'keydown', UP_ARROW); fixture.detectChanges(); - expect(calendarInstance._activeDate).toEqual(new Date(2017, MAY, 10)); + expect(calendarInstance._activeDate).toEqual(new Date(2017, AUG, 10)); }); it('should go down a row on down arrow press', () => { dispatchKeyboardEvent(calendarBodyEl, 'keydown', DOWN_ARROW); fixture.detectChanges(); - expect(calendarInstance._activeDate).toEqual(new Date(2017, AUG, 31)); + expect(calendarInstance._activeDate).toEqual(new Date(2017, MAY, 31)); calendarInstance._activeDate = new Date(2017, JUN, 1); fixture.detectChanges(); @@ -372,7 +373,7 @@ describe('MatCalendar', () => { dispatchKeyboardEvent(calendarBodyEl, 'keydown', DOWN_ARROW); fixture.detectChanges(); - expect(calendarInstance._activeDate).toEqual(new Date(2018, JUN, 1)); + expect(calendarInstance._activeDate).toEqual(new Date(2017, OCT, 1)); calendarInstance._activeDate = new Date(2017, SEP, 30); fixture.detectChanges(); @@ -380,7 +381,7 @@ describe('MatCalendar', () => { dispatchKeyboardEvent(calendarBodyEl, 'keydown', DOWN_ARROW); fixture.detectChanges(); - expect(calendarInstance._activeDate).toEqual(new Date(2018, FEB, 28)); + expect(calendarInstance._activeDate).toEqual(new Date(2018, JAN, 30)); }); it('should go to first month of the year on home press', () => { diff --git a/src/lib/datepicker/calendar.ts b/src/lib/datepicker/calendar.ts index aeef7512aab2..d7d76ddbf64e 100644 --- a/src/lib/datepicker/calendar.ts +++ b/src/lib/datepicker/calendar.ts @@ -312,6 +312,7 @@ export class MatCalendar implements AfterContentInit, OnDestroy, OnChanges { case ENTER: if (this._dateFilterForViews(this._activeDate)) { this._dateSelected(this._activeDate); + this._userSelected(); // Prevent unexpected default actions such as form submission. event.preventDefault(); } @@ -375,11 +376,8 @@ export class MatCalendar implements AfterContentInit, OnDestroy, OnChanges { * calendar table. */ private _prevMonthInSameCol(date: D): D { - // Determine how many months to jump forward given that there are 2 empty slots at the beginning - // of each year. - let increment = this._dateAdapter.getMonth(date) <= 4 ? -5 : - (this._dateAdapter.getMonth(date) >= 7 ? -7 : -12); - return this._dateAdapter.addCalendarMonths(date, increment); + // Decrement by 4 since there are 4 months per row. + return this._dateAdapter.addCalendarMonths(date, -4); } /** @@ -387,11 +385,8 @@ export class MatCalendar implements AfterContentInit, OnDestroy, OnChanges { * calendar table. */ private _nextMonthInSameCol(date: D): D { - // Determine how many months to jump forward given that there are 2 empty slots at the beginning - // of each year. - let increment = this._dateAdapter.getMonth(date) <= 4 ? 7 : - (this._dateAdapter.getMonth(date) >= 7 ? 5 : 12); - return this._dateAdapter.addCalendarMonths(date, increment); + // Increment by 4 since there are 4 months per row. + return this._dateAdapter.addCalendarMonths(date, 4); } /** diff --git a/src/lib/datepicker/datepicker.spec.ts b/src/lib/datepicker/datepicker.spec.ts index 3e06b855fd35..eadd19caf9ff 100644 --- a/src/lib/datepicker/datepicker.spec.ts +++ b/src/lib/datepicker/datepicker.spec.ts @@ -1,9 +1,10 @@ -import {ESCAPE} from '@angular/cdk/keycodes'; +import {ENTER, ESCAPE, RIGHT_ARROW} from '@angular/cdk/keycodes'; import {OverlayContainer} from '@angular/cdk/overlay'; import { createKeyboardEvent, dispatchEvent, dispatchFakeEvent, + dispatchKeyboardEvent, dispatchMouseEvent, } from '@angular/cdk/testing'; import {Component, ViewChild} from '@angular/core'; @@ -203,7 +204,7 @@ describe('MatDatepicker', () => { }); })); - it('setting selected should update input and close calendar', async(() => { + it('setting selected via click should update input and close calendar', async(() => { testComponent.touch = true; fixture.detectChanges(); @@ -223,8 +224,31 @@ describe('MatDatepicker', () => { }); })); + it('setting selected via enter press should update input and close calendar', () => { + testComponent.touch = true; + fixture.detectChanges(); + + testComponent.datepicker.open(); + fixture.detectChanges(); + + expect(document.querySelector('mat-dialog-container')).not.toBeNull(); + expect(testComponent.datepickerInput.value).toEqual(new Date(2020, JAN, 1)); + + let calendarBodyEl = document.querySelector('.mat-calendar-content') as HTMLElement; + + dispatchKeyboardEvent(calendarBodyEl, 'keydown', RIGHT_ARROW); + fixture.detectChanges(); + dispatchKeyboardEvent(calendarBodyEl, 'keydown', ENTER); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + expect(document.querySelector('mat-dialog-container')).toBeNull(); + expect(testComponent.datepickerInput.value).toEqual(new Date(2020, JAN, 2)); + }); + }); + it('clicking the currently selected date should close the calendar ' + - 'without firing selectedChanged', () => { + 'without firing selectedChanged', () => { const selectedChangedSpy = spyOn(testComponent.datepicker.selectedChanged, 'emit').and.callThrough(); @@ -246,6 +270,28 @@ describe('MatDatepicker', () => { expect(testComponent.datepickerInput.value).toEqual(new Date(2020, JAN, 2)); }); + it('pressing enter on the currently selected date should close the calendar without ' + + 'firing selectedChanged', () => { + const selectedChangedSpy = + spyOn(testComponent.datepicker.selectedChanged, 'emit').and.callThrough(); + + testComponent.datepicker.open(); + fixture.detectChanges(); + + let calendarBodyEl = document.querySelector('.mat-calendar-content') as HTMLElement; + expect(calendarBodyEl).not.toBeNull(); + expect(testComponent.datepickerInput.value).toEqual(new Date(2020, JAN, 1)); + + dispatchKeyboardEvent(calendarBodyEl, 'keydown', ENTER); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + expect(selectedChangedSpy.calls.count()).toEqual(0); + expect(document.querySelector('mat-dialog-container')).toBeNull(); + expect(testComponent.datepickerInput.value).toEqual(new Date(2020, JAN, 1)); + }); + }); + it('startAt should fallback to input value', () => { expect(testComponent.datepicker.startAt).toEqual(new Date(2020, JAN, 1)); });