Angular-2-material mat-ink-bar not on default tab

2.7k views Asked by At

I am trying to lay out tabs on my website and I am using md-tab-group to achieve this. I am unable to get the ink-bar to be on the default but however, the content written on the respective tab is available. The ink-bar appears on click and not on init of the page. Below is my code

<md-tab-group dynamicHeight = "true" >
   <md-tab id="hello1" label="Tab 1">
    <!-- some content here -->
   </md-tab>

   <md-tab id="hello2" label="Tab 2">
  <!-- some content here -->
   </md-tab>

</md-tab-group>

The solutions that I have tried are a) selectedIndex not working in md-tab-group when dynamically generating tabs b) Angular Material Tabs SelectedIndex 0 not working

Any idea what am I overlooking?

3

There are 3 answers

0
Simon_Weaver On

I was getting this same issue with mat-tab-nav-bar, which is the same control but where you don't define blocks of content for each tab in advance.

Turns out (for me) that my tab bar was not visible on the page when it was first being initialized. It was actually nested within another tab, but the point it that it can't figure out the width when it's not visible.

enter image description here

So everything worked perfectly except the inkBar (the blue bar) had a width of 0px.

The solution is going to vary depending upon your page, but this may help diagnose things.

  • Search for this._inkBarPositioner in your browser
  • Put a breakpoint here and see if width is zero.

If you're using nested tabs and seeing this issue you may be able to fix it by switching to a templated tab (which is called asynchronously loaded tab in the docs).

The function MatTabBar._alignInkBarToSelectedTab is private but you could try to call it as a last resort once you know the control is actually visible.

Hacky solution #1

nav.mat-tab-nav-bar ::ng-deep .mat-ink-bar
{
    min-width: 160px;  // or whatever your min size is
}

This css is targeted for mat-tab-nav-bar (the standalone tab navigation bar) and not mat-tab-group / mat-tab but could almost certainly be adjusted to fit the tab / group control.

0
Marshal On

I would recommend upgrading your angular and material versions, md- indicates you are using an older version of the material library.

Please review this stackblitz example using a current version of material library... please note the new syntax.

<mat-tab-group>
  <mat-tab label="First"> Content 1 </mat-tab>
  <mat-tab label="Second"> Content 2 </mat-tab>
  <mat-tab label="Third"> Content 3 </mat-tab>
</mat-tab-group>

https://stackblitz.com/angular/earngvqxaaon?file=app%2Ftab-group-basic-example.html

1
Devin On

My default tab wasn't getting the ink bar to underline the default tab on initial load. I couldn't find a fix with documentation or searching, because it should work out of the box... I think it's a problem with changeDetection: ChangeDetectionStrategy.OnPush and drawing the ink bar initially. Having a timeout that will realign the ink bar seems to get the behavior I wanted. Here's my hacky solution (that I don't like, so if someone has a better fix, I would love to hear it):

component.html:

<mat-tab-group [selectedIndex]="0">
  <mat-tab label="one"></mat-tab>
  <mat-tab label="two"></mat-tab>
  <mat-tab label="three"></mat-tab>
</mat-tab-group>

component.ts (using changeDetection: ChangeDetectionStrategy.OnPush):

  // hook into the ngAfterViewInit lifecycle hook to get the tab group object
  @ViewChild(MatTabGroup, { static: false }) tabGroup!: MatTabGroup;

  // after view check, should have populated the tab group
  ngAfterViewInit(): void {
    // hacky solution to get the ink bar to draw the initial underline:
    timer(2500)
      .pipe(take(1))
      .subscribe(() => this.tabGroup.realignInkBar());
  }

EDIT: Found an open issue on GitHub: https://github.com/angular/components/issues/11811