@@ -16,6 +16,7 @@ import {
16
16
PositionStrategy ,
17
17
RepositionScrollStrategy ,
18
18
ScrollStrategy ,
19
+ ConnectedPositionStrategy ,
19
20
} from '@angular/cdk/overlay' ;
20
21
import { ComponentPortal } from '@angular/cdk/portal' ;
21
22
import { take } from 'rxjs/operators/take' ;
@@ -35,6 +36,8 @@ import {
35
36
ViewChild ,
36
37
ViewContainerRef ,
37
38
ViewEncapsulation ,
39
+ ChangeDetectorRef ,
40
+ OnInit ,
38
41
} from '@angular/core' ;
39
42
import { DateAdapter } from '@angular/material/core' ;
40
43
import { MatDialog , MatDialogRef } from '@angular/material/dialog' ;
@@ -44,6 +47,7 @@ import {Subscription} from 'rxjs/Subscription';
44
47
import { MatCalendar } from './calendar' ;
45
48
import { createMissingDateImplError } from './datepicker-errors' ;
46
49
import { MatDatepickerInput } from './datepicker-input' ;
50
+ import { trigger , state , style , animate , transition } from '@angular/animations' ;
47
51
48
52
49
53
/** Used to generate a unique ID for each datepicker instance. */
@@ -81,23 +85,73 @@ export const MAT_DATEPICKER_SCROLL_STRATEGY_PROVIDER = {
81
85
styleUrls : [ 'datepicker-content.css' ] ,
82
86
host : {
83
87
'class' : 'mat-datepicker-content' ,
88
+ '[@tranformPanel]' : '"enter"' ,
84
89
'[class.mat-datepicker-content-touch]' : 'datepicker.touchUi' ,
90
+ '[class.mat-datepicker-content-above]' : '_isAbove' ,
85
91
'(keydown)' : '_handleKeydown($event)' ,
86
92
} ,
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
+ ] ,
87
106
exportAs : 'matDatepickerContent' ,
88
107
encapsulation : ViewEncapsulation . None ,
89
108
preserveWhitespaces : false ,
90
109
changeDetection : ChangeDetectionStrategy . OnPush ,
91
110
} )
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 ;
94
114
115
+ /** Reference to the internal calendar component. */
95
116
@ViewChild ( MatCalendar ) _calendar : MatCalendar < D > ;
96
117
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
+
97
144
ngAfterContentInit ( ) {
98
145
this . _calendar . _focusActiveCell ( ) ;
99
146
}
100
147
148
+ ngOnDestroy ( ) {
149
+ if ( this . _positionChange ) {
150
+ this . _positionChange . unsubscribe ( ) ;
151
+ this . _positionChange = null ;
152
+ }
153
+ }
154
+
101
155
/**
102
156
* Handles keydown event on datepicker content.
103
157
* @param event The event.
@@ -214,7 +268,7 @@ export class MatDatepicker<D> implements OnDestroy {
214
268
}
215
269
216
270
/** A reference to the overlay when the calendar is opened as a popup. */
217
- private _popupRef : OverlayRef ;
271
+ _popupRef : OverlayRef ;
218
272
219
273
/** A reference to the dialog when the calendar is opened as a dialog. */
220
274
private _dialogRef : MatDialogRef < any > | null ;
0 commit comments