@@ -16,6 +16,7 @@ import {
1616 PositionStrategy ,
1717 RepositionScrollStrategy ,
1818 ScrollStrategy ,
19+ ConnectedPositionStrategy ,
1920} from '@angular/cdk/overlay' ;
2021import { ComponentPortal } from '@angular/cdk/portal' ;
2122import { first } from 'rxjs/operators/first' ;
@@ -35,6 +36,8 @@ import {
3536 ViewChild ,
3637 ViewContainerRef ,
3738 ViewEncapsulation ,
39+ ChangeDetectorRef ,
40+ OnInit ,
3841} from '@angular/core' ;
3942import { DateAdapter } from '@angular/material/core' ;
4043import { MatDialog , MatDialogRef } from '@angular/material/dialog' ;
@@ -44,6 +47,7 @@ import {Subscription} from 'rxjs/Subscription';
4447import { MatCalendar } from './calendar' ;
4548import { createMissingDateImplError } from './datepicker-errors' ;
4649import { MatDatepickerInput } from './datepicker-input' ;
50+ import { trigger , state , style , animate , transition } from '@angular/animations' ;
4751
4852
4953/** Used to generate a unique ID for each datepicker instance. */
@@ -81,23 +85,73 @@ export const MAT_DATEPICKER_SCROLL_STRATEGY_PROVIDER = {
8185 styleUrls : [ 'datepicker-content.css' ] ,
8286 host : {
8387 'class' : 'mat-datepicker-content' ,
88+ '[@tranformPanel]' : '"enter"' ,
8489 '[class.mat-datepicker-content-touch]' : 'datepicker.touchUi' ,
90+ '[class.mat-datepicker-content-above]' : '_isAbove' ,
8591 '(keydown)' : '_handleKeydown($event)' ,
8692 } ,
93+ animations : [
94+ trigger ( 'tranformPanel' , [
95+ state ( 'void' , style ( { opacity : 0 , transform : 'scale(1, 0)' } ) ) ,
96+ state ( 'enter' , style ( { opacity : 1 , transform : 'scale(1, 1)' } ) ) ,
97+ transition ( 'void => enter' , animate ( '400ms cubic-bezier(0.25, 0.8, 0.25, 1)' ) ) ,
98+ transition ( '* => void' , animate ( '100ms linear' , style ( { opacity : 0 } ) ) )
99+ ] ) ,
100+ trigger ( 'fadeInCalendar' , [
101+ state ( 'void' , style ( { opacity : 0 } ) ) ,
102+ state ( 'enter' , style ( { opacity : 1 } ) ) ,
103+ transition ( 'void => *' , animate ( '400ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)' ) )
104+ ] )
105+ ] ,
87106 exportAs : 'matDatepickerContent' ,
88107 encapsulation : ViewEncapsulation . None ,
89108 preserveWhitespaces : false ,
90109 changeDetection : ChangeDetectionStrategy . OnPush ,
91110} )
92- export class MatDatepickerContent < D > implements AfterContentInit {
93- datepicker : MatDatepicker < D > ;
111+ export class MatDatepickerContent < D > implements AfterContentInit , OnInit , OnDestroy {
112+ /** Subscription to changes in the overlay's position. */
113+ private _positionChange : Subscription | null ;
94114
115+ /** Reference to the internal calendar component. */
95116 @ViewChild ( MatCalendar ) _calendar : MatCalendar < D > ;
96117
118+ /** Reference to the datepicker that created the overlay. */
119+ datepicker : MatDatepicker < D > ;
120+
121+ /** Whether the datepicker is above or below the input. */
122+ _isAbove : boolean ;
123+
124+ constructor ( private _changeDetectorRef : ChangeDetectorRef ) { }
125+
126+ ngOnInit ( ) {
127+ if ( ! this . datepicker . _popupRef || this . _positionChange ) {
128+ return ;
129+ }
130+
131+ const positionStrategy =
132+ this . datepicker . _popupRef . getConfig ( ) . positionStrategy ! as ConnectedPositionStrategy ;
133+
134+ this . _positionChange = positionStrategy . onPositionChange . subscribe ( change => {
135+ const isAbove = change . connectionPair . overlayY === 'bottom' ;
136+
137+ if ( isAbove !== this . _isAbove ) {
138+ this . _isAbove = isAbove ;
139+ this . _changeDetectorRef . markForCheck ( ) ;
140+ }
141+ } ) ;
142+ }
143+
97144 ngAfterContentInit ( ) {
98145 this . _calendar . _focusActiveCell ( ) ;
99146 }
100147
148+ ngOnDestroy ( ) {
149+ if ( this . _positionChange ) {
150+ this . _positionChange . unsubscribe ( ) ;
151+ this . _positionChange = null ;
152+ }
153+ }
154+
101155 /**
102156 * Handles keydown event on datepicker content.
103157 * @param event The event.
@@ -211,7 +265,7 @@ export class MatDatepicker<D> implements OnDestroy {
211265 }
212266
213267 /** A reference to the overlay when the calendar is opened as a popup. */
214- private _popupRef : OverlayRef ;
268+ _popupRef : OverlayRef ;
215269
216270 /** A reference to the dialog when the calendar is opened as a dialog. */
217271 private _dialogRef : MatDialogRef < any > | null ;
0 commit comments