Skip to content

Commit 2deaab8

Browse files
hilts-vaughancrisbeto
authored andcommitted
fix(material/tabs): ensure the ink bar realigns when the tab header items have changed in dimensions (#24885)
(cherry picked from commit 2ced52a)
1 parent 0c453c9 commit 2deaab8

File tree

1 file changed

+42
-3
lines changed

1 file changed

+42
-3
lines changed

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

Lines changed: 42 additions & 3 deletions
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,36 @@ export abstract class MatPaginatedTabHeader
246255
});
247256
}
248257

258+
/** Sends any changes that could affect the layout of the items. */
259+
private _itemsResized(): Observable<void> {
260+
if (typeof ResizeObserver !== 'function') {
261+
return EMPTY;
262+
}
263+
264+
return this._items.changes.pipe(
265+
startWith(this._items),
266+
switchMap(
267+
(tabItems: QueryList<MatPaginatedTabHeaderItem>) =>
268+
new Observable((observer: Observer<void>) =>
269+
this._ngZone.runOutsideAngular(() => {
270+
const resizeObserver = new ResizeObserver(() => {
271+
observer.next();
272+
});
273+
tabItems.forEach(item => {
274+
resizeObserver.observe(item.elementRef.nativeElement);
275+
});
276+
return () => {
277+
resizeObserver.disconnect();
278+
};
279+
}),
280+
),
281+
),
282+
// Skip the first emit since the resize observer emits when an item
283+
// is observed for new items when the tab is already inserted
284+
skip(1),
285+
);
286+
}
287+
249288
ngAfterContentChecked(): void {
250289
// If the number of tab labels have changed, check if scrolling should be enabled
251290
if (this._tabLabelCount != this._items.length) {

0 commit comments

Comments
 (0)