Skip to content

Commit 8611a74

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 6f7584a commit 8611a74

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
@@ -26,8 +26,17 @@ import {coerceNumberProperty, NumberInput} from '@angular/cdk/coercion';
2626
import {ViewportRuler} from '@angular/cdk/scrolling';
2727
import {FocusKeyManager, FocusableOption} from '@angular/cdk/a11y';
2828
import {ENTER, SPACE, hasModifierKey} from '@angular/cdk/keycodes';
29-
import {merge, of as observableOf, Subject, timer, fromEvent} from 'rxjs';
30-
import {take, takeUntil} from 'rxjs/operators';
29+
import {
30+
merge,
31+
of as observableOf,
32+
Subject,
33+
EMPTY,
34+
Observer,
35+
Observable,
36+
timer,
37+
fromEvent,
38+
} from 'rxjs';
39+
import {take, switchMap, startWith, skip, takeUntil} from 'rxjs/operators';
3140
import {Platform, normalizePassiveListenerOptions} from '@angular/cdk/platform';
3241
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
3342

@@ -207,7 +216,7 @@ export abstract class MatPaginatedTabHeader
207216

208217
// On dir change or window resize, realign the ink bar and update the orientation of
209218
// the key manager if the direction has changed.
210-
merge(dirChange, resize, this._items.changes)
219+
merge(dirChange, resize, this._items.changes, this._itemsResized())
211220
.pipe(takeUntil(this._destroyed))
212221
.subscribe(() => {
213222
// We need to defer this to give the browser some time to recalculate
@@ -235,6 +244,36 @@ export abstract class MatPaginatedTabHeader
235244
});
236245
}
237246

247+
/** Sends any changes that could affect the layout of the items. */
248+
private _itemsResized(): Observable<void> {
249+
if (typeof ResizeObserver !== 'function') {
250+
return EMPTY;
251+
}
252+
253+
return this._items.changes.pipe(
254+
startWith(this._items),
255+
switchMap(
256+
(tabItems: QueryList<MatPaginatedTabHeaderItem>) =>
257+
new Observable((observer: Observer<void>) =>
258+
this._ngZone.runOutsideAngular(() => {
259+
const resizeObserver = new ResizeObserver(() => {
260+
observer.next();
261+
});
262+
tabItems.forEach(item => {
263+
resizeObserver.observe(item.elementRef.nativeElement);
264+
});
265+
return () => {
266+
resizeObserver.disconnect();
267+
};
268+
}),
269+
),
270+
),
271+
// Skip the first emit since the resize observer emits when an item
272+
// is observed for new items when the tab is already inserted
273+
skip(1),
274+
);
275+
}
276+
238277
ngAfterContentChecked(): void {
239278
// If the number of tab labels have changed, check if scrolling should be enabled
240279
if (this._tabLabelCount != this._items.length) {

0 commit comments

Comments
 (0)