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 . 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,45 @@ 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
+ /**
159
+ * @deletion -target 7.0.0 changeDetectorRef to be made required.
160
+ */
161
+ changeDetectorRef ?: ChangeDetectorRef ) {
162
+
163
+ if ( this . _dir && changeDetectorRef ) {
164
+ this . _dirChangeSubscription = this . _dir . change . subscribe ( dir => {
165
+ this . _computePositionAnimationState ( dir ) ;
166
+ changeDetectorRef . markForCheck ( ) ;
167
+ } ) ;
158
168
}
159
169
}
160
- _origin : MatTabBodyOriginState ;
161
-
162
- constructor ( private _elementRef : ElementRef ,
163
- @Optional ( ) private _dir : Directionality ) { }
164
170
165
171
/**
166
172
* After initialized, check if the content is centered and has an origin. If so, set the
167
173
* special position states that transition the tab from the left or right before centering.
168
174
*/
169
175
ngOnInit ( ) {
170
- if ( this . _position == 'center' && this . _origin ) {
171
- this . _position = this . _origin == 'left' ? 'left-origin-center' : 'right-origin-center' ;
176
+ if ( this . _position == 'center' && this . origin !== undefined ) {
177
+ this . _position = this . _computePositionFromOrigin ( ) ;
172
178
}
173
179
}
174
180
181
+ ngOnDestroy ( ) {
182
+ this . _dirChangeSubscription . unsubscribe ( ) ;
183
+ }
184
+
175
185
_onTranslateTabStarted ( e : AnimationEvent ) : void {
176
186
const isCentering = this . _isCenterPosition ( e . toState ) ;
177
187
this . _beforeCentering . emit ( isCentering ) ;
@@ -202,4 +212,29 @@ export class MatTabBody implements OnInit {
202
212
position == 'left-origin-center' ||
203
213
position == 'right-origin-center' ;
204
214
}
215
+
216
+ /** Computes the position state that will be used for the tab-body animation trigger. */
217
+ private _computePositionAnimationState ( dir : Direction = this . _getLayoutDirection ( ) ) {
218
+ if ( this . _positionIndex < 0 ) {
219
+ this . _position = dir == 'ltr' ? 'left' : 'right' ;
220
+ } else if ( this . _positionIndex > 0 ) {
221
+ this . _position = dir == 'ltr' ? 'right' : 'left' ;
222
+ } else {
223
+ this . _position = 'center' ;
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Computes the position state based on the specified origin position. This is used if the
229
+ * tab is becoming visible immediately after creation.
230
+ */
231
+ private _computePositionFromOrigin ( ) : MatTabBodyPositionState {
232
+ const dir = this . _getLayoutDirection ( ) ;
233
+
234
+ if ( ( dir == 'ltr' && this . origin <= 0 ) || ( dir == 'rtl' && this . origin > 0 ) ) {
235
+ return 'left-origin-center' ;
236
+ }
237
+
238
+ return 'right-origin-center' ;
239
+ }
205
240
}
0 commit comments