@@ -230,9 +230,7 @@ export class MatMonthView<D> implements AfterContentInit, OnChanges, OnDestroy {
230
230
/** Handles when a new date is selected. */
231
231
_dateSelected ( event : MatCalendarUserEvent < number > ) {
232
232
const date = event . value ;
233
- const selectedYear = this . _dateAdapter . getYear ( this . activeDate ) ;
234
- const selectedMonth = this . _dateAdapter . getMonth ( this . activeDate ) ;
235
- const selectedDate = this . _dateAdapter . createDate ( selectedYear , selectedMonth , date ) ;
233
+ const selectedDate = this . _getDateFromDayOfMonth ( date ) ;
236
234
let rangeStartDate : number | null ;
237
235
let rangeEndDate : number | null ;
238
236
@@ -252,6 +250,26 @@ export class MatMonthView<D> implements AfterContentInit, OnChanges, OnDestroy {
252
250
this . _changeDetectorRef . markForCheck ( ) ;
253
251
}
254
252
253
+ /**
254
+ * Takes the index of a calendar body cell wrapped in in an event as argument. For the date that
255
+ * corresponds to the given cell, set `activeDate` to that date and fire `activeDateChange` with
256
+ * that date.
257
+ *
258
+ * This fucntion is used to match each component's model of the active date with the calendar
259
+ * body cell that was focused. It updates its value of `activeDate` synchronously and updates the
260
+ * parent's value asynchonously via the `activeDateChange` event. The child component receives an
261
+ * updated value asynchronously via the `activeCell` Input.
262
+ */
263
+ _updateActiveDate ( event : MatCalendarUserEvent < number > ) {
264
+ const month = event . value ;
265
+ const oldActiveDate = this . _activeDate ;
266
+ this . activeDate = this . _getDateFromDayOfMonth ( month ) ;
267
+
268
+ if ( this . _dateAdapter . compareDate ( oldActiveDate , this . activeDate ) ) {
269
+ this . activeDateChange . emit ( this . _activeDate ) ;
270
+ }
271
+ }
272
+
255
273
/** Handles keydown events on the calendar body when calendar is in month view. */
256
274
_handleCalendarBodyKeydown ( event : KeyboardEvent ) : void {
257
275
// TODO(mmalerba): We currently allow keyboard navigation to disabled dates, but just prevent
@@ -327,9 +345,10 @@ export class MatMonthView<D> implements AfterContentInit, OnChanges, OnDestroy {
327
345
328
346
if ( this . _dateAdapter . compareDate ( oldActiveDate , this . activeDate ) ) {
329
347
this . activeDateChange . emit ( this . activeDate ) ;
348
+
349
+ this . _focusActiveCellAfterViewChecked ( ) ;
330
350
}
331
351
332
- this . _focusActiveCell ( ) ;
333
352
// Prevent unexpected default actions such as form submission.
334
353
event . preventDefault ( ) ;
335
354
}
@@ -376,6 +395,11 @@ export class MatMonthView<D> implements AfterContentInit, OnChanges, OnDestroy {
376
395
this . _matCalendarBody . _focusActiveCell ( movePreview ) ;
377
396
}
378
397
398
+ /** Focuses the active cell after change detection has run and the microtask queue is empty. */
399
+ _focusActiveCellAfterViewChecked ( ) {
400
+ this . _matCalendarBody . _scheduleFocusActiveCellAfterViewChecked ( ) ;
401
+ }
402
+
379
403
/** Called when the user has activated a new cell and the preview needs to be updated. */
380
404
_previewChanged ( { event, value : cell } : MatCalendarUserEvent < MatCalendarCell < D > | null > ) {
381
405
if ( this . _rangeStrategy ) {
@@ -398,6 +422,18 @@ export class MatMonthView<D> implements AfterContentInit, OnChanges, OnDestroy {
398
422
}
399
423
}
400
424
425
+ /**
426
+ * Takes a day of the month and returns a new date in the same month and year as the currently
427
+ * active date. The returned date will have the same day of the month as the argument date.
428
+ */
429
+ private _getDateFromDayOfMonth ( dayOfMonth : number ) : D {
430
+ return this . _dateAdapter . createDate (
431
+ this . _dateAdapter . getYear ( this . activeDate ) ,
432
+ this . _dateAdapter . getMonth ( this . activeDate ) ,
433
+ dayOfMonth ,
434
+ ) ;
435
+ }
436
+
401
437
/** Initializes the weekdays. */
402
438
private _initWeekdays ( ) {
403
439
const firstDayOfWeek = this . _dateAdapter . getFirstDayOfWeek ( ) ;
0 commit comments