From 9f36400f46788ca4c13f912c9db3fbe5e3176a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=87etin?= <92744169+mehmetcetin01140@users.noreply.github.com> Date: Mon, 8 Jul 2024 17:51:56 +0300 Subject: [PATCH] Fixed #15973 - TabMenu doesn't scroll to active item when it's set programatically --- src/app/components/tabmenu/tabmenu.ts | 53 ++++++++++----------------- 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/src/app/components/tabmenu/tabmenu.ts b/src/app/components/tabmenu/tabmenu.ts index 77aa1165c53..c3bcd5f0bb8 100644 --- a/src/app/components/tabmenu/tabmenu.ts +++ b/src/app/components/tabmenu/tabmenu.ts @@ -12,10 +12,10 @@ import { Inject, Input, NgModule, - OnDestroy, Output, PLATFORM_ID, QueryList, + SimpleChanges, TemplateRef, ViewChild, ViewChildren, @@ -132,7 +132,7 @@ import { filter } from 'rxjs/operators'; class: 'p-element' } }) -export class TabMenu implements AfterContentInit, AfterViewInit, AfterViewChecked, OnDestroy { +export class TabMenu implements AfterContentInit, AfterViewInit, AfterViewChecked { /** * An array of menuitems. * @group Props @@ -225,8 +225,6 @@ export class TabMenu implements AfterContentInit, AfterViewInit, AfterViewChecke forwardIsDisabled: boolean = false; - private timerIdForInitialAutoScroll: any = null; - _focusableItems: MenuItem[] | undefined | any; _model: MenuItem[] | undefined; @@ -257,6 +255,19 @@ export class TabMenu implements AfterContentInit, AfterViewInit, AfterViewChecke }); } + ngOnChanges(simpleChange: SimpleChanges) { + if (simpleChange.activeItem) { + if (!this.scrollable) { + return; + } + const activeItem = (this.model as MenuItem[]).findIndex((menuItem) => this.isActive(menuItem)); + + if (activeItem !== -1) { + this.updateScrollBar(activeItem); + } + } + } + ngAfterContentInit() { this.templates?.forEach((item) => { switch (item.getType()) { @@ -282,7 +293,7 @@ export class TabMenu implements AfterContentInit, AfterViewInit, AfterViewChecke ngAfterViewInit(): void { if (isPlatformBrowser(this.platformId)) { this.updateInkBar(); - this.initAutoScrollForActiveItem(); + this.initButtonState(); } } @@ -294,10 +305,6 @@ export class TabMenu implements AfterContentInit, AfterViewInit, AfterViewChecke } } - ngOnDestroy(): void { - this.clearAutoScrollHandler(); - } - isActive(item: MenuItem) { if (item.routerLink) { const routerLink = Array.isArray(item.routerLink) ? item.routerLink : [item.routerLink]; @@ -342,6 +349,7 @@ export class TabMenu implements AfterContentInit, AfterViewInit, AfterViewChecke } this.activeItem = item; + this.activeItemChange.emit(item); this.tabChanged = true; this.cd.markForCheck(); @@ -460,7 +468,9 @@ export class TabMenu implements AfterContentInit, AfterViewInit, AfterViewChecke return; } - tabHeader.scrollIntoView({ block: 'nearest', inline: 'center' }); + if (tabHeader && typeof tabHeader.scrollIntoView === 'function') { + tabHeader.scrollIntoView({ block: 'nearest', inline: 'center' }); + } } onScroll(event: Event) { @@ -484,29 +494,6 @@ export class TabMenu implements AfterContentInit, AfterViewInit, AfterViewChecke content.scrollLeft = pos >= lastPos ? lastPos : pos; } - private initAutoScrollForActiveItem(): void { - if (!this.scrollable) { - return; - } - - this.clearAutoScrollHandler(); - // We have to wait for the rendering and then can scroll to element. - this.timerIdForInitialAutoScroll = setTimeout(() => { - const activeItem = (this.model as MenuItem[]).findIndex((menuItem) => this.isActive(menuItem)); - - if (activeItem !== -1) { - this.updateScrollBar(activeItem); - } - }); - } - - private clearAutoScrollHandler(): void { - if (this.timerIdForInitialAutoScroll) { - clearTimeout(this.timerIdForInitialAutoScroll); - this.timerIdForInitialAutoScroll = null; - } - } - private initButtonState(): void { if (this.scrollable) { // We have to wait for the rendering and then retrieve the actual size element from the DOM.