Skip to content

Commit 5bf036c

Browse files
committed
fix(material/tabs): ensure the ink bar realigns when the tab header items have changed in dimensions
1 parent a47869c commit 5bf036c

File tree

1 file changed

+47
-3
lines changed

1 file changed

+47
-3
lines changed

src/material/tabs/paginated-tab-header.ts

+47-3
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,17 @@ import {
3131
import {ViewportRuler} from '@angular/cdk/scrolling';
3232
import {FocusKeyManager, FocusableOption} from '@angular/cdk/a11y';
3333
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';
3645
import {Platform, normalizePassiveListenerOptions} from '@angular/cdk/platform';
3746
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
3847

@@ -218,7 +227,7 @@ export abstract class MatPaginatedTabHeader
218227

219228
// On dir change or window resize, realign the ink bar and update the orientation of
220229
// the key manager if the direction has changed.
221-
merge(dirChange, resize, this._items.changes)
230+
merge(dirChange, resize, this._items.changes, this._itemsResized())
222231
.pipe(takeUntil(this._destroyed))
223232
.subscribe(() => {
224233
// We need to defer this to give the browser some time to recalculate
@@ -246,6 +255,41 @@ export abstract class MatPaginatedTabHeader
246255
});
247256
}
248257

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+
249293
ngAfterContentChecked(): void {
250294
// If the number of tab labels have changed, check if scrolling should be enabled
251295
if (this._tabLabelCount != this._items.length) {

0 commit comments

Comments
 (0)