Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 15.1 mat-tab-nav-bar require TabPanel

I recently upgraded my project to Angular 15.1 and noticed a new problem.

On a page I have a mat-tab-nav which opene subpages via routing:

<nav mat-tab-nav-bar color="primary">
  <a mat-tab-link *ngFor="let link of navLinks" [routerLink]="link.link" routerLinkActive #rla="routerLinkActive" [active]="rla.isActive">{{link.label}}< /a>
</nav>
<router-outlet></router-outlet>

After the update everything works fine but in the console I see the error "A mat-tab-nav-panel must be specified via [tabPanel]."

Looking at the Angular code (line 385) https://github.com/angular/components/blob/main/src/material/tabs/tab-nav-bar/tab-nav-bar.ts I see the code:

override ngAfterViewInit() {
 if (!this.tabPanel && (typeof ngDevMode === 'undefined' || ngDevMode)) {
   throw new Error('A mat-tab-nav-panel must be specified via [tabPanel].');
 }
 super.ngAfterViewInit();
}

From the documentation (https://material.angular.io/components/tabs/api tabPanel) it looks like the tabPanel may be null:

tabPanel: associated tab panel controlled by the nav bar. If not provided, then the nav bar follows the ARIA link / navigation landmark pattern. If provided, it follows the ARIA tabs design pattern.

I fixed it by adding a useless mat-tab-nav-panel to my code:

<nav mat-tab-nav-bar color="primary" [tabPanel]="tabPanel">
  <a mat-tab-link *ngFor="let link of navLinks" [routerLink]="link.link" routerLinkActive #rla="routerLinkActive" [active]="rla.isActive">{{link.label}}< /a>
</nav>
<mat-tab-nav-panel #tabPanel></mat-tab-nav-panel>
<router-outlet></router-outlet>

Is this the correct way? It seems to me a bug of the Angular component. What do you think?

like image 930
Gabriele Muscas Avatar asked Sep 06 '25 17:09

Gabriele Muscas


1 Answers

In my Opinion you have to wrap the Router Outlet in an <mat-tab-nav-panel>:

<nav mat-tab-nav-bar color="primary" [tabPanel]="tabPanel">
  <a mat-tab-link *ngFor="let link of navLinks" [routerLink]="link.link" routerLinkActive #rla="routerLinkActive" [active]="rla.isActive">{{link.label}}< /a>
</nav>
<mat-tab-nav-panel #tabPanel>
  <router-outlet></router-outlet>
</mat-tab-nav-panel>

The Documentaton states
"The corresponding <router-outlet> must be wrapped in an <mat-tab-nav-panel> component and should typically be placed relatively close to the mat-tab-nav-bar (see Accessibility)."
see Angular Material Tabs: Tabs and navigation
Although the code example from Angular Team is currently missing the Router-Outlet.

like image 85
JIT Solution Avatar answered Sep 11 '25 02:09

JIT Solution