Skip to content

Commit c8d8ef2

Browse files
authored
fix(material/tabs): scroll position lost when tab header is hidden (#25855)
In #24885 a `ResizeObserver` was added to the tabs so that the ink bar can re-align if the tab is resized. The problem is that the observer will fire when the tabs become invisible as well, causing the header to re-render using incorrect dimensions. Fixes #25574.
1 parent 94b694f commit c8d8ef2

File tree

1 file changed

+8
-9
lines changed

1 file changed

+8
-9
lines changed

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import {
4141
timer,
4242
fromEvent,
4343
} from 'rxjs';
44-
import {take, switchMap, startWith, skip, takeUntil} from 'rxjs/operators';
44+
import {take, switchMap, startWith, skip, takeUntil, filter} from 'rxjs/operators';
4545
import {Platform, normalizePassiveListenerOptions} from '@angular/cdk/platform';
4646
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
4747

@@ -256,7 +256,7 @@ export abstract class MatPaginatedTabHeader
256256
}
257257

258258
/** Sends any changes that could affect the layout of the items. */
259-
private _itemsResized(): Observable<void> {
259+
private _itemsResized(): Observable<ResizeObserverEntry[]> {
260260
if (typeof ResizeObserver !== 'function') {
261261
return EMPTY;
262262
}
@@ -265,14 +265,10 @@ export abstract class MatPaginatedTabHeader
265265
startWith(this._items),
266266
switchMap(
267267
(tabItems: QueryList<MatPaginatedTabHeaderItem>) =>
268-
new Observable((observer: Observer<void>) =>
268+
new Observable((observer: Observer<ResizeObserverEntry[]>) =>
269269
this._ngZone.runOutsideAngular(() => {
270-
const resizeObserver = new ResizeObserver(() => {
271-
observer.next();
272-
});
273-
tabItems.forEach(item => {
274-
resizeObserver.observe(item.elementRef.nativeElement);
275-
});
270+
const resizeObserver = new ResizeObserver(entries => observer.next(entries));
271+
tabItems.forEach(item => resizeObserver.observe(item.elementRef.nativeElement));
276272
return () => {
277273
resizeObserver.disconnect();
278274
};
@@ -282,6 +278,9 @@ export abstract class MatPaginatedTabHeader
282278
// Skip the first emit since the resize observer emits when an item
283279
// is observed for new items when the tab is already inserted
284280
skip(1),
281+
// Skip emissions where all the elements are invisible since we don't want
282+
// the header to try and re-render with invalid measurements. See #25574.
283+
filter(entries => entries.some(e => e.contentRect.width > 0 && e.contentRect.height > 0)),
285284
);
286285
}
287286

0 commit comments

Comments
 (0)