From 527412ff329659232305389b20001b73cbb9cd04 Mon Sep 17 00:00:00 2001 From: Haoxin Yang <1810849666@qq.com> Date: Thu, 6 Jun 2024 16:19:23 +0800 Subject: [PATCH 1/4] fix: tab header paginator not show without viewport resize --- src/tabs/tab-header.component.ts | 33 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/tabs/tab-header.component.ts b/src/tabs/tab-header.component.ts index edc837612..f29c78cd2 100644 --- a/src/tabs/tab-header.component.ts +++ b/src/tabs/tab-header.component.ts @@ -20,7 +20,7 @@ import { ViewChild, ViewEncapsulation, } from '@angular/core'; -import { Subject, takeUntil } from 'rxjs'; +import { Subject, debounceTime, merge, takeUntil } from 'rxjs'; import { IconComponent } from '../icon/icon.component'; import { Bem, buildBem } from '../internal/utils'; @@ -95,11 +95,11 @@ export class TabHeaderComponent /** Used to manage focus between the tabs. */ private _keyManager: FocusKeyManager; - /** - * The number of tab labels that are displayed on the header. When this changes, the header - * should re-evaluate the scroll position. - */ - private _tabLabelCount: number; + private readonly _resizeObserver = new ResizeObserver(() => + this.tabListResize$$.next(), + ); + + private readonly tabListResize$$ = new Subject(); @Input() type: TabType = TabType.Line; @@ -157,16 +157,11 @@ export class TabHeaderComponent ngOnDestroy() { this._destroyed.next(); this._destroyed.complete(); + + this._resizeObserver.unobserve(this._tabList.nativeElement); } ngAfterContentChecked(): void { - // If the number of tab labels have changed, check if scrolling should be enabled - if (this._tabLabelCount !== this._labelWrappers.length) { - this._updatePagination(); - this._tabLabelCount = this._labelWrappers.length; - this._changeDetectorRef.markForCheck(); - } - // If the selected index has changed, scroll to the label and check if the scrolling controls // should be disabled. if (this._selectedIndexChanged) { @@ -196,7 +191,7 @@ export class TabHeaderComponent * Aligns the ink bar to the selected tab on load. */ ngAfterContentInit() { - const resize = this._viewportRuler.change(150); + const resize$ = this._viewportRuler.change(150); const realign = () => { this._updatePagination(); this._alignActiveIndicatorToSelectedTab(); @@ -214,11 +209,13 @@ export class TabHeaderComponent // This helps in cases where the user lands directly on a page with paginated tabs. requestAnimationFrame(realign); - // On window resize, realign the ink bar and update the orientation of + this._resizeObserver.observe(this._tabList.nativeElement); + + // On window resize or tab list resize, realign the ink bar and update the orientation of // the key manager if the direction has changed. - resize.pipe(takeUntil(this._destroyed)).subscribe(() => { - realign(); - }); + merge(resize$, this.tabListResize$$) + .pipe(debounceTime(100), takeUntil(this._destroyed)) + .subscribe(realign); // If there is a change in the focus key manager we need to emit the `indexFocused` // event in order to provide a public event that notifies about focus changes. Also we realign From 1368d58c976adbd56502622bb5d6939a66f16262 Mon Sep 17 00:00:00 2001 From: Haoxin Yang <1810849666@qq.com> Date: Thu, 6 Jun 2024 18:48:02 +0800 Subject: [PATCH 2/4] feat: use observeResizeOn instead and mod stream --- jest.setup.ts | 6 ++++++ src/tabs/tab-header.component.ts | 25 +++++-------------------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/jest.setup.ts b/jest.setup.ts index 127128ebe..88dedb811 100644 --- a/jest.setup.ts +++ b/jest.setup.ts @@ -22,3 +22,9 @@ Object.defineProperty(window, 'matchMedia', { dispatchEvent: jest.fn(), })), }); + +global.ResizeObserver = jest.fn().mockImplementation(() => ({ + observe: jest.fn(), + unobserve: jest.fn(), + disconnect: jest.fn(), +})); diff --git a/src/tabs/tab-header.component.ts b/src/tabs/tab-header.component.ts index f29c78cd2..b57feb92f 100644 --- a/src/tabs/tab-header.component.ts +++ b/src/tabs/tab-header.component.ts @@ -1,7 +1,6 @@ import { FocusKeyManager } from '@angular/cdk/a11y'; import { ObserversModule } from '@angular/cdk/observers'; import { PortalModule } from '@angular/cdk/portal'; -import { ViewportRuler } from '@angular/cdk/scrolling'; import { NgClass, NgIf } from '@angular/common'; import { AfterContentChecked, @@ -20,10 +19,10 @@ import { ViewChild, ViewEncapsulation, } from '@angular/core'; -import { Subject, debounceTime, merge, takeUntil } from 'rxjs'; +import { Subject, debounceTime, takeUntil } from 'rxjs'; import { IconComponent } from '../icon/icon.component'; -import { Bem, buildBem } from '../internal/utils'; +import { Bem, buildBem, observeResizeOn } from '../internal/utils'; import { TabHeaderAddonDirective, @@ -95,12 +94,6 @@ export class TabHeaderComponent /** Used to manage focus between the tabs. */ private _keyManager: FocusKeyManager; - private readonly _resizeObserver = new ResizeObserver(() => - this.tabListResize$$.next(), - ); - - private readonly tabListResize$$ = new Subject(); - @Input() type: TabType = TabType.Line; @@ -157,8 +150,6 @@ export class TabHeaderComponent ngOnDestroy() { this._destroyed.next(); this._destroyed.complete(); - - this._resizeObserver.unobserve(this._tabList.nativeElement); } ngAfterContentChecked(): void { @@ -191,7 +182,6 @@ export class TabHeaderComponent * Aligns the ink bar to the selected tab on load. */ ngAfterContentInit() { - const resize$ = this._viewportRuler.change(150); const realign = () => { this._updatePagination(); this._alignActiveIndicatorToSelectedTab(); @@ -209,11 +199,9 @@ export class TabHeaderComponent // This helps in cases where the user lands directly on a page with paginated tabs. requestAnimationFrame(realign); - this._resizeObserver.observe(this._tabList.nativeElement); - - // On window resize or tab list resize, realign the ink bar and update the orientation of + // On tab list resize, realign the ink bar and update the orientation of // the key manager if the direction has changed. - merge(resize$, this.tabListResize$$) + observeResizeOn(this._tabList.nativeElement) .pipe(debounceTime(100), takeUntil(this._destroyed)) .subscribe(realign); @@ -453,8 +441,5 @@ export class TabHeaderComponent this._activeIndicator.alignToElement(selectedLabelWrapper); } - constructor( - private readonly _changeDetectorRef: ChangeDetectorRef, - private readonly _viewportRuler: ViewportRuler, - ) {} + constructor(private readonly _changeDetectorRef: ChangeDetectorRef) {} } From 8b9c3424b07f31585ada3e63e5b032244a2be250 Mon Sep 17 00:00:00 2001 From: Haoxin Yang <1810849666@qq.com> Date: Tue, 11 Jun 2024 11:24:24 +0800 Subject: [PATCH 3/4] feat: mod detect dom resize and realign --- src/tabs/tab-header.component.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tabs/tab-header.component.ts b/src/tabs/tab-header.component.ts index b57feb92f..6a260f398 100644 --- a/src/tabs/tab-header.component.ts +++ b/src/tabs/tab-header.component.ts @@ -19,7 +19,7 @@ import { ViewChild, ViewEncapsulation, } from '@angular/core'; -import { Subject, debounceTime, takeUntil } from 'rxjs'; +import { Subject, debounceTime, merge, takeUntil } from 'rxjs'; import { IconComponent } from '../icon/icon.component'; import { Bem, buildBem, observeResizeOn } from '../internal/utils'; @@ -195,13 +195,13 @@ export class TabHeaderComponent .withWrap(); this._keyManager.updateActiveItem(0); - // Defer the first call in order to allow for slower browsers to lay out the elements. - // This helps in cases where the user lands directly on a page with paginated tabs. - requestAnimationFrame(realign); - // On tab list resize, realign the ink bar and update the orientation of // the key manager if the direction has changed. - observeResizeOn(this._tabList.nativeElement) + merge( + observeResizeOn(this._tabList.nativeElement), + observeResizeOn(this._tabListContainer.nativeElement), + observeResizeOn(this._paginationWrapper.nativeElement), + ) .pipe(debounceTime(100), takeUntil(this._destroyed)) .subscribe(realign); From 9bb3fb273b4d13f198d33adbf2c55d26564d438c Mon Sep 17 00:00:00 2001 From: Mrlang <1810849666@qq.com> Date: Wed, 12 Jun 2024 16:29:18 +0800 Subject: [PATCH 4/4] Create small-sheep-train.md --- .changeset/small-sheep-train.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/small-sheep-train.md diff --git a/.changeset/small-sheep-train.md b/.changeset/small-sheep-train.md new file mode 100644 index 000000000..b66ce6dbc --- /dev/null +++ b/.changeset/small-sheep-train.md @@ -0,0 +1,5 @@ +--- +"@alauda/ui": patch +--- + +fix: tab header paginator not show without viewport resize