8
8
9
9
import {
10
10
Component ,
11
+ ChangeDetectorRef ,
11
12
Input ,
12
13
Inject ,
13
14
Output ,
@@ -113,7 +114,17 @@ export class MatTabBodyPortal extends CdkPortalOutlet implements OnInit, OnDestr
113
114
'class' : 'mat-tab-body' ,
114
115
} ,
115
116
} )
116
- export class MatTabBody implements OnInit {
117
+ export class MatTabBody implements OnInit , OnDestroy {
118
+
119
+ /** Current position of the tab-body in the tab-group. Zero means that the tab is visible. */
120
+ private _positionIndex : number ;
121
+
122
+ /** Subscription to the directionality change observable. */
123
+ private _dirChangeSubscription : Subscription = Subscription . EMPTY ;
124
+
125
+ /** Tab body position state. Used by the animation trigger for the current state. */
126
+ _position : MatTabBodyPositionState ;
127
+
117
128
/** Event emitted when the tab begins to animate towards the center as the active tab. */
118
129
@Output ( ) readonly _onCentering : EventEmitter < number > = new EventEmitter < number > ( ) ;
119
130
@@ -132,46 +143,43 @@ export class MatTabBody implements OnInit {
132
143
/** The tab body content to display. */
133
144
@Input ( 'content' ) _content : TemplatePortal ;
134
145
146
+ /** Position that will be used when the tab is immediately becoming visible after creation. */
147
+ @Input ( ) origin : number ;
148
+
135
149
/** The shifted index position of the tab body, where zero represents the active center tab. */
136
150
@Input ( )
137
151
set position ( position : number ) {
138
- if ( position < 0 ) {
139
- this . _position = this . _getLayoutDirection ( ) == 'ltr' ? 'left' : 'right' ;
140
- } else if ( position > 0 ) {
141
- this . _position = this . _getLayoutDirection ( ) == 'ltr' ? 'right' : 'left' ;
142
- } else {
143
- this . _position = 'center' ;
144
- }
152
+ this . _positionIndex = position ;
153
+ this . _computePositionAnimationState ( ) ;
145
154
}
146
- _position : MatTabBodyPositionState ;
147
-
148
- /** The origin position from which this tab should appear when it is centered into view. */
149
- @Input ( )
150
- set origin ( origin : number ) {
151
- if ( origin == null ) { return ; }
152
155
153
- const dir = this . _getLayoutDirection ( ) ;
154
- if ( ( dir == 'ltr' && origin <= 0 ) || ( dir == 'rtl' && origin > 0 ) ) {
155
- this . _origin = 'left' ;
156
- } else {
157
- this . _origin = 'right' ;
156
+ constructor ( private _elementRef : ElementRef ,
157
+ @Optional ( ) private _dir : Directionality ,
158
+ // TODO(paul): make the changeDetectorRef required when doing breaking changes.
159
+ changeDetectorRef ?: ChangeDetectorRef ) {
160
+
161
+ if ( this . _dir && changeDetectorRef ) {
162
+ this . _dir . change . subscribe ( dir => {
163
+ this . _computePositionAnimationState ( dir ) ;
164
+ changeDetectorRef . markForCheck ( ) ;
165
+ } ) ;
158
166
}
159
167
}
160
- _origin : MatTabBodyOriginState ;
161
-
162
- constructor ( private _elementRef : ElementRef ,
163
- @Optional ( ) private _dir : Directionality ) { }
164
168
165
169
/**
166
170
* After initialized, check if the content is centered and has an origin. If so, set the
167
171
* special position states that transition the tab from the left or right before centering.
168
172
*/
169
173
ngOnInit ( ) {
170
- if ( this . _position == 'center' && this . _origin ) {
171
- this . _position = this . _origin == 'left' ? 'left-origin-center' : 'right-origin-center' ;
174
+ if ( this . _position == 'center' && this . origin !== undefined ) {
175
+ this . _position = this . _computePositionFromOrigin ( ) ;
172
176
}
173
177
}
174
178
179
+ ngOnDestroy ( ) {
180
+ this . _dirChangeSubscription . unsubscribe ( ) ;
181
+ }
182
+
175
183
_onTranslateTabStarted ( e : AnimationEvent ) : void {
176
184
const isCentering = this . _isCenterPosition ( e . toState ) ;
177
185
this . _beforeCentering . emit ( isCentering ) ;
@@ -202,4 +210,29 @@ export class MatTabBody implements OnInit {
202
210
position == 'left-origin-center' ||
203
211
position == 'right-origin-center' ;
204
212
}
213
+
214
+ /** Computes the position state that will be used for the tab-body animation trigger. */
215
+ private _computePositionAnimationState ( dir : Direction = this . _getLayoutDirection ( ) ) {
216
+ if ( this . _positionIndex < 0 ) {
217
+ this . _position = dir == 'ltr' ? 'left' : 'right' ;
218
+ } else if ( this . _positionIndex > 0 ) {
219
+ this . _position = dir == 'ltr' ? 'right' : 'left' ;
220
+ } else {
221
+ this . _position = 'center' ;
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Computes the position state based on the specified origin position. This is used if the
227
+ * tab is becoming visible immediately after creation.
228
+ */
229
+ private _computePositionFromOrigin ( ) : MatTabBodyPositionState {
230
+ const dir = this . _getLayoutDirection ( ) ;
231
+
232
+ if ( ( dir == 'ltr' && this . origin <= 0 ) || ( dir == 'rtl' && this . origin > 0 ) ) {
233
+ return 'left-origin-center' ;
234
+ } else {
235
+ return 'right-origin-center' ;
236
+ }
237
+ }
205
238
}
0 commit comments