diff --git a/src/app/header/tabs/tabs.component.ts b/src/app/header/tabs/tabs.component.ts index e19fadc9..fc951d26 100644 --- a/src/app/header/tabs/tabs.component.ts +++ b/src/app/header/tabs/tabs.component.ts @@ -29,23 +29,30 @@ import { TabComponent } from '../tab/tab.component' changeDetection: ChangeDetectionStrategy.OnPush, }) export class TabsComponent implements OnDestroy { - public _intersectionObserver!: IntersectionObserver protected readonly MaterialSymbol = { KeyboardDoubleArrowLeft, KeyboardDoubleArrowRight, } - protected _prevButtonDisabled = signal(true) - protected _nextButtonDisabled = signal(true) + private _tabs = contentChildren(TabComponent, { descendants: false, }) + // Pagination private _tabList = viewChild>('tabList') private _firstTab?: ElementRef private _lastTab?: ElementRef + protected _prevButtonDisabled = signal(true) + protected _nextButtonDisabled = signal(true) + public _intersectionObserver!: IntersectionObserver + // Selected management private _currentTabs: ReadonlyArray = [] private _indexToSelect?: number + private _selectedIndex?: number + @Input({ transform: numberAttribute }) set selectedIndex(index: number) { + this._indexToSelect = index + } /// Scroll to selected private _indexToScrollTo?: number @@ -67,41 +74,6 @@ export class TabsComponent implements OnDestroy { effect(this._onTabsChanged.bind(this)) } - private _selectedIndex?: number - - @Input({ transform: numberAttribute }) set selectedIndex(index: number) { - this._indexToSelect = index - } - - ngOnDestroy(): void { - this._intersectionObserver?.disconnect() - } - - protected _scrollABit(scrollDirection: ScrollDirection) { - const tabListContainer = this._tabList()?.nativeElement - /* istanbul ignore next */ - if (!tabListContainer) { - if (isDevMode) { - console.log( - 'TabsComponent: Not scrolling. Reason: tab list container element is missing', - ) - } - return - } - //👇 Amount to scroll extracted from MatTab - // https://github.com/angular/components/blob/18.0.5/src/material/tabs/paginated-tab-header.ts#L473-L488 - const tabListContainerLength = tabListContainer.offsetWidth - const scrollAmount = tabListContainerLength / 3 - const newScrollPosition = Math.max( - tabListContainer.scrollLeft + scrollAmount * scrollDirection, - 0, - ) - tabListContainer.scrollTo({ - behavior: 'smooth', - left: newScrollPosition, - }) - } - private _updateSelectedIfNeeded(): void { if ( this._indexToSelect === undefined || @@ -134,6 +106,10 @@ export class TabsComponent implements OnDestroy { this._indexToScrollTo = undefined } + ngOnDestroy(): void { + this._intersectionObserver?.disconnect() + } + private _onTabsChanged() { const tabs = this._tabs() if (!this._intersectionObserver || tabs.length === 0) { @@ -174,6 +150,30 @@ export class TabsComponent implements OnDestroy { }, ) } + protected _scrollABit(scrollDirection: ScrollDirection) { + const tabListContainer = this._tabList()?.nativeElement + /* istanbul ignore next */ + if (!tabListContainer) { + if (isDevMode) { + console.log( + 'TabsComponent: Not scrolling. Reason: tab list container element is missing', + ) + } + return + } + //👇 Amount to scroll extracted from MatTab + // https://github.com/angular/components/blob/18.0.5/src/material/tabs/paginated-tab-header.ts#L473-L488 + const tabListContainerLength = tabListContainer.offsetWidth + const scrollAmount = tabListContainerLength / 3 + const newScrollPosition = Math.max( + tabListContainer.scrollLeft + scrollAmount * scrollDirection, + 0, + ) + tabListContainer.scrollTo({ + behavior: 'smooth', + left: newScrollPosition, + }) + } } const INTERSECTION_THRESHOLD = 0.8