@@ -36,6 +36,7 @@ import {
3636 ViewChild ,
3737 ViewContainerRef ,
3838 ViewEncapsulation ,
39+ ElementRef ,
3940} from '@angular/core' ;
4041import { DateAdapter } from '@angular/material/core' ;
4142import { MatDialog , MatDialogRef } from '@angular/material/dialog' ;
@@ -46,6 +47,7 @@ import {merge} from 'rxjs/observable/merge';
4647import { MatCalendar } from './calendar' ;
4748import { createMissingDateImplError } from './datepicker-errors' ;
4849import { MatDatepickerInput } from './datepicker-input' ;
50+ import { CanColor , mixinColor , ThemePalette } from '@angular/material/core' ;
4951
5052
5153/** Used to generate a unique ID for each datepicker instance. */
@@ -68,6 +70,12 @@ export const MAT_DATEPICKER_SCROLL_STRATEGY_PROVIDER = {
6870 useFactory : MAT_DATEPICKER_SCROLL_STRATEGY_PROVIDER_FACTORY ,
6971} ;
7072
73+ // Boilerplate for applying mixins to MatDatepickerContent.
74+ /** @docs -private */
75+ export class MatDatepickerContentBase {
76+ constructor ( public _elementRef : ElementRef ) { }
77+ }
78+ export const _MatDatepickerContentMixinBase = mixinColor ( MatDatepickerContentBase ) ;
7179
7280/**
7381 * Component used as the content for the datepicker dialog and popup. We use this instead of using
@@ -89,12 +97,18 @@ export const MAT_DATEPICKER_SCROLL_STRATEGY_PROVIDER = {
8997 encapsulation : ViewEncapsulation . None ,
9098 preserveWhitespaces : false ,
9199 changeDetection : ChangeDetectionStrategy . OnPush ,
100+ inputs : [ 'color' ] ,
92101} )
93- export class MatDatepickerContent < D > implements AfterContentInit {
102+ export class MatDatepickerContent < D > extends _MatDatepickerContentMixinBase
103+ implements AfterContentInit , CanColor {
94104 datepicker : MatDatepicker < D > ;
95105
96106 @ViewChild ( MatCalendar ) _calendar : MatCalendar < D > ;
97107
108+ constructor ( elementRef : ElementRef ) {
109+ super ( elementRef ) ;
110+ }
111+
98112 ngAfterContentInit ( ) {
99113 this . _calendar . _focusActiveCell ( ) ;
100114 }
@@ -114,7 +128,7 @@ export class MatDatepickerContent<D> implements AfterContentInit {
114128 encapsulation : ViewEncapsulation . None ,
115129 preserveWhitespaces : false ,
116130} )
117- export class MatDatepicker < D > implements OnDestroy {
131+ export class MatDatepicker < D > implements OnDestroy , CanColor {
118132 /** The date to open the calendar to initially. */
119133 @Input ( )
120134 get startAt ( ) : D | null {
@@ -130,6 +144,9 @@ export class MatDatepicker<D> implements OnDestroy {
130144 /** The view that the calendar should start in. */
131145 @Input ( ) startView : 'month' | 'year' = 'month' ;
132146
147+ /** Color palette to use on the datepicker's calendar. */
148+ @Input ( ) color : ThemePalette ;
149+
133150 /**
134151 * Whether the calendar UI is in touch mode. In touch mode the calendar opens in a dialog rather
135152 * than a popup and elements have more padding to allow for bigger touch targets.
@@ -206,14 +223,18 @@ export class MatDatepicker<D> implements OnDestroy {
206223 private _popupRef : OverlayRef ;
207224
208225 /** A reference to the dialog when the calendar is opened as a dialog. */
209- private _dialogRef : MatDialogRef < any > | null ;
226+ private _dialogRef : MatDialogRef < MatDatepickerContent < D > > | null ;
210227
211228 /** A portal containing the calendar for this datepicker. */
212229 private _calendarPortal : ComponentPortal < MatDatepickerContent < D > > ;
213230
231+ /** Reference to the component instantiated in popup mode. */
232+ private _popupComponentRef : ComponentRef < MatDatepickerContent < D > > | null ;
233+
214234 /** The element that was focused before the datepicker was opened. */
215235 private _focusedElementBeforeOpen : HTMLElement | null = null ;
216236
237+ /** Subscription to value changes in the associated input element. */
217238 private _inputSubscription = Subscription . EMPTY ;
218239
219240 /** The input element this datepicker is associated with. */
@@ -242,6 +263,7 @@ export class MatDatepicker<D> implements OnDestroy {
242263
243264 if ( this . _popupRef ) {
244265 this . _popupRef . dispose ( ) ;
266+ this . _popupComponentRef = null ;
245267 }
246268 }
247269
@@ -333,6 +355,7 @@ export class MatDatepicker<D> implements OnDestroy {
333355 } ) ;
334356 this . _dialogRef . afterClosed ( ) . subscribe ( ( ) => this . close ( ) ) ;
335357 this . _dialogRef . componentInstance . datepicker = this ;
358+ this . _setColor ( ) ;
336359 }
337360
338361 /** Open the calendar as a popup. */
@@ -346,9 +369,9 @@ export class MatDatepicker<D> implements OnDestroy {
346369 }
347370
348371 if ( ! this . _popupRef . hasAttached ( ) ) {
349- let componentRef : ComponentRef < MatDatepickerContent < D > > =
350- this . _popupRef . attach ( this . _calendarPortal ) ;
351- componentRef . instance . datepicker = this ;
372+ this . _popupComponentRef = this . _popupRef . attach ( this . _calendarPortal ) ;
373+ this . _popupComponentRef . instance . datepicker = this ;
374+ this . _setColor ( ) ;
352375
353376 // Update the position once the calendar has rendered.
354377 this . _ngZone . onStable . asObservable ( ) . pipe ( take ( 1 ) ) . subscribe ( ( ) => {
@@ -411,4 +434,18 @@ export class MatDatepicker<D> implements OnDestroy {
411434 private _getValidDateOrNull ( obj : any ) : D | null {
412435 return ( this . _dateAdapter . isDateInstance ( obj ) && this . _dateAdapter . isValid ( obj ) ) ? obj : null ;
413436 }
437+
438+ /** Passes the current theme color along to the calendar overlay. */
439+ private _setColor ( ) : void {
440+ const input = this . _datepickerInput ;
441+ const color = this . color || ( input ? input . _getThemePalette ( ) : undefined ) ;
442+
443+ if ( this . _popupComponentRef ) {
444+ this . _popupComponentRef . instance . color = color ;
445+ }
446+
447+ if ( this . _dialogRef ) {
448+ this . _dialogRef . componentInstance . color = color ;
449+ }
450+ }
414451}
0 commit comments