diff --git a/projects/ngx-dsfr-components/src/lib/components/tabs/tabs.component.ts b/projects/ngx-dsfr-components/src/lib/components/tabs/tabs.component.ts index a9e461331b89bb140529556088eb664d47de59b3..f139a8b8034cc8f4f84931f2e4fb14fc35ddf867 100644 --- a/projects/ngx-dsfr-components/src/lib/components/tabs/tabs.component.ts +++ b/projects/ngx-dsfr-components/src/lib/components/tabs/tabs.component.ts @@ -9,8 +9,7 @@ import { QueryList, ViewEncapsulation, } from '@angular/core'; - -import { Router } from '@angular/router'; +import { ActivatedRoute, NavigationExtras, Router } from '@angular/router'; import { newUniqueId } from '../../shared'; import { DsfrTabComponent } from './tab.component'; import { BUTTON_TAB_ID_PREFIX, DsfrTabRoute, EduTabHeader } from './tabs.model'; @@ -55,7 +54,11 @@ export class DsfrTabsComponent { /** @internal */ routerTabId: string; - constructor(@Optional() private router: Router, private elRef: ElementRef) { + constructor( + @Optional() private router: Router, + @Optional() private activatedRoute: ActivatedRoute, + private elRef: ElementRef, + ) { this.routerTabId = newUniqueId(); } @@ -63,6 +66,10 @@ export class DsfrTabsComponent { return this.routes || this.tabComponents?.toArray(); } + private get tabsCount(): number { + return this.routes ? this.routes.length : this.tabComponents ? this.tabComponents.length : 0; + } + /** @internal */ getHeaderValue(header: EduTabHeader, key: string): any { return header[<never>key]; @@ -116,41 +123,49 @@ export class DsfrTabsComponent { * @internal */ onButtonTabKeydown(event: KeyboardEvent, index: number): void { + // just in case if (this.selectedTabIndex !== index) return; + let newIndex = -1; + switch (event.code) { case 'ArrowLeft': - if (this.selectedTabIndex === 0) { - this.performKeyAction(this.routes.length - 1); - } else { - this.performKeyAction(this.selectedTabIndex - 1); - } + newIndex = this.isFirstTab(index) ? this.tabsCount - 1 : index - 1; break; case 'ArrowRight': - if (this.selectedTabIndex === this.routes.length - 1) { - this.performKeyAction(0); - } else { - this.performKeyAction(this.selectedTabIndex + 1); - } + newIndex = this.isLastTab(index) ? 0 : index + 1; break; case 'Home': - this.performKeyAction(0); + newIndex = 0; break; case 'End': - this.performKeyAction(this.routes.length - 1); + newIndex = this.tabsCount - 1; break; default: break; } + + if (newIndex > -1) { + this.performKeyAction(newIndex); + } + } + + private isFirstTab(index: number): boolean { + return index === 0; + } + + private isLastTab(index: number): boolean { + return index === this.tabsCount - 1; } private performKeyAction(newIndex: number) { const route = this.routes[newIndex]; - this.router.navigate([route.path], route.routerLinkExtras); + const extras: NavigationExtras = route.routerLinkExtras || { relativeTo: this.activatedRoute }; + this.router.navigate([route.path], extras); this.elRef.nativeElement.querySelector('#' + this.getButtonTabId(route))?.focus(); } }