@@ -37,7 +37,7 @@ import {Subject} from 'rxjs/Subject';
37
37
import { MdSnackBarConfig } from './snack-bar-config' ;
38
38
39
39
40
- export type SnackBarState = 'initial' | ' visible' | 'complete ' | 'void' ;
40
+ export type SnackBarState = 'visible' | 'hidden ' | 'void' ;
41
41
42
42
// TODO(jelbourn): we can't use constants from animation.ts here because you can't use
43
43
// a text interpolation in anything that is analyzed statically with ngc (for AoT compile).
@@ -58,17 +58,22 @@ export const HIDE_ANIMATION = '195ms cubic-bezier(0.0,0.0,0.2,1)';
58
58
host : {
59
59
'role' : 'alert' ,
60
60
'class' : 'mat-snack-bar-container' ,
61
- '[@state]' : 'animationState ' ,
61
+ '[@state]' : 'getAnimationState() ' ,
62
62
'(@state.done)' : 'onAnimationEnd($event)'
63
63
} ,
64
64
animations : [
65
65
trigger ( 'state' , [
66
- state ( 'void' , style ( { transform : 'translateY(100%)' } ) ) ,
67
- state ( 'initial' , style ( { transform : 'translateY(100%)' } ) ) ,
68
- state ( 'visible' , style ( { transform : 'translateY(0%)' } ) ) ,
69
- state ( 'complete' , style ( { transform : 'translateY(100%)' } ) ) ,
70
- transition ( 'visible => complete' , animate ( HIDE_ANIMATION ) ) ,
71
- transition ( 'initial => visible, void => visible' , animate ( SHOW_ANIMATION ) ) ,
66
+ // Animation from top.
67
+ state ( 'visible-top' , style ( { transform : 'translateY(0%)' } ) ) ,
68
+ state ( 'hidden-top' , style ( { transform : 'translateY(-100%)' } ) ) ,
69
+ transition ( 'visible-top => hidden-top' , animate ( HIDE_ANIMATION ) ) ,
70
+ transition ( 'void => visible-top' , animate ( SHOW_ANIMATION ) ) ,
71
+ // Animation from bottom.
72
+ state ( 'visible-bottom' , style ( { transform : 'translateY(0%)' } ) ) ,
73
+ state ( 'hidden-bottom' , style ( { transform : 'translateY(100%)' } ) ) ,
74
+ transition ( 'visible-bottom => hidden-bottom' , animate ( HIDE_ANIMATION ) ) ,
75
+ transition ( 'void => visible-bottom' ,
76
+ animate ( SHOW_ANIMATION ) ) ,
72
77
] )
73
78
] ,
74
79
} )
@@ -83,7 +88,7 @@ export class MdSnackBarContainer extends BasePortalHost implements OnDestroy {
83
88
private onEnter : Subject < any > = new Subject ( ) ;
84
89
85
90
/** The state of the snack bar animations. */
86
- animationState : SnackBarState = 'initial' ;
91
+ private _animationState : SnackBarState ;
87
92
88
93
/** The snack bar configuration. */
89
94
snackBarConfig : MdSnackBarConfig ;
@@ -95,6 +100,14 @@ export class MdSnackBarContainer extends BasePortalHost implements OnDestroy {
95
100
super ( ) ;
96
101
}
97
102
103
+ /**
104
+ * Gets the current animation state both combining one of the possibilities from
105
+ * SnackBarState and the vertical location.
106
+ */
107
+ getAnimationState ( ) : string {
108
+ return `${ this . _animationState } -${ this . snackBarConfig . verticalPosition } ` ;
109
+ }
110
+
98
111
/** Attach a component portal as content to this snack bar container. */
99
112
attachComponentPortal < T > ( portal : ComponentPortal < T > ) : ComponentRef < T > {
100
113
if ( this . _portalHost . hasAttached ( ) ) {
@@ -109,6 +122,14 @@ export class MdSnackBarContainer extends BasePortalHost implements OnDestroy {
109
122
}
110
123
}
111
124
125
+ if ( this . snackBarConfig . horizontalPosition === 'center' ) {
126
+ this . _renderer . addClass ( this . _elementRef . nativeElement , 'mat-snack-bar-center' ) ;
127
+ }
128
+
129
+ if ( this . snackBarConfig . verticalPosition === 'top' ) {
130
+ this . _renderer . addClass ( this . _elementRef . nativeElement , 'mat-snack-bar-top' ) ;
131
+ }
132
+
112
133
return this . _portalHost . attachComponentPortal ( portal ) ;
113
134
}
114
135
@@ -119,15 +140,14 @@ export class MdSnackBarContainer extends BasePortalHost implements OnDestroy {
119
140
120
141
/** Handle end of animations, updating the state of the snackbar. */
121
142
onAnimationEnd ( event : AnimationEvent ) {
122
- if ( event . toState === 'void' || event . toState === 'complete' ) {
143
+ if ( event . toState === 'void' || event . toState . startsWith ( 'hidden' ) ) {
123
144
this . _completeExit ( ) ;
124
145
}
125
146
126
- if ( event . toState === 'visible' ) {
147
+ if ( event . toState . startsWith ( 'visible' ) ) {
127
148
// Note: we shouldn't use `this` inside the zone callback,
128
149
// because it can cause a memory leak.
129
150
const onEnter = this . onEnter ;
130
-
131
151
this . _ngZone . run ( ( ) => {
132
152
onEnter . next ( ) ;
133
153
onEnter . complete ( ) ;
@@ -137,18 +157,18 @@ export class MdSnackBarContainer extends BasePortalHost implements OnDestroy {
137
157
138
158
/** Begin animation of snack bar entrance into view. */
139
159
enter ( ) : void {
140
- this . animationState = 'visible' ;
160
+ this . _animationState = 'visible' ;
141
161
}
142
162
143
163
/** Returns an observable resolving when the enter animation completes. */
144
164
_onEnter ( ) : Observable < void > {
145
- this . animationState = 'visible' ;
165
+ this . _animationState = 'visible' ;
146
166
return this . onEnter . asObservable ( ) ;
147
167
}
148
168
149
169
/** Begin animation of the snack bar exiting from view. */
150
170
exit ( ) : Observable < void > {
151
- this . animationState = 'complete ' ;
171
+ this . _animationState = 'hidden ' ;
152
172
return this . _onExit ( ) ;
153
173
}
154
174
0 commit comments