@@ -31,8 +31,17 @@ import {
31
31
import { ViewportRuler } from '@angular/cdk/scrolling' ;
32
32
import { FocusKeyManager , FocusableOption } from '@angular/cdk/a11y' ;
33
33
import { ENTER , SPACE , hasModifierKey } from '@angular/cdk/keycodes' ;
34
- import { merge , of as observableOf , Subject , timer , fromEvent } from 'rxjs' ;
35
- import { take , takeUntil } from 'rxjs/operators' ;
34
+ import {
35
+ merge ,
36
+ of as observableOf ,
37
+ Subject ,
38
+ EMPTY ,
39
+ Observer ,
40
+ Observable ,
41
+ timer ,
42
+ fromEvent ,
43
+ } from 'rxjs' ;
44
+ import { take , switchMap , startWith , skip , takeUntil } from 'rxjs/operators' ;
36
45
import { Platform , normalizePassiveListenerOptions } from '@angular/cdk/platform' ;
37
46
import { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations' ;
38
47
@@ -218,7 +227,7 @@ export abstract class MatPaginatedTabHeader
218
227
219
228
// On dir change or window resize, realign the ink bar and update the orientation of
220
229
// the key manager if the direction has changed.
221
- merge ( dirChange , resize , this . _items . changes )
230
+ merge ( dirChange , resize , this . _items . changes , this . _itemsResized ( ) )
222
231
. pipe ( takeUntil ( this . _destroyed ) )
223
232
. subscribe ( ( ) => {
224
233
// We need to defer this to give the browser some time to recalculate
@@ -246,6 +255,41 @@ export abstract class MatPaginatedTabHeader
246
255
} ) ;
247
256
}
248
257
258
+ /** A method responsible for sending any change that could affect layout about
259
+ * the items in this tab bar.
260
+ */
261
+ private _itemsResized ( ) : Observable < void > {
262
+ if ( typeof ResizeObserver !== 'function' ) {
263
+ return EMPTY ;
264
+ }
265
+
266
+ return this . _items . changes . pipe (
267
+ startWith ( this . _items ) ,
268
+ switchMap (
269
+ ( tabItems : QueryList < MatPaginatedTabHeaderItem > ) =>
270
+ new Observable ( ( observer : Observer < void > ) =>
271
+ this . _ngZone . runOutsideAngular ( ( ) => {
272
+ const resizeObserver = new ResizeObserver ( ( ) => {
273
+ observer . next ( ) ;
274
+ } ) ;
275
+ tabItems . forEach ( item => {
276
+ resizeObserver . observe ( item . elementRef . nativeElement ) ;
277
+ } ) ;
278
+ return ( ) => {
279
+ resizeObserver . disconnect ( ) ;
280
+ } ;
281
+ } ) ,
282
+ ) ,
283
+ ) ,
284
+ // Skip the first emit since the resize observer emits when an item
285
+ // is observed for new items when the tab is already inserted
286
+ skip ( 1 ) ,
287
+
288
+ // Fire initial resize so the DOM can adjust the very first time
289
+ startWith ( undefined ) ,
290
+ ) ;
291
+ }
292
+
249
293
ngAfterContentChecked ( ) : void {
250
294
// If the number of tab labels have changed, check if scrolling should be enabled
251
295
if ( this . _tabLabelCount != this . _items . length ) {
0 commit comments