components icon indicating copy to clipboard operation
components copied to clipboard

bug(tabs / mat-tab-group): Open dialog with component mat-tab-group and fast change mat-tab (click another mat-tab) and empty content

Open fildasabo opened this issue 3 years ago • 3 comments
trafficstars

Is this a regression?

  • [ ] Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

If I open a dialog in which I have a mat-tab-group component and quickly click on another tab (another mat-tab), the content of the newly opened tab is not rendered - it remains empty. It looks right in DOM.

There are several ways to quickly change a tab:

  1. By touch
  2. Click the mouse
  3. By entering the click command in the console: document.evaluate('//html[1]/body[1]/div[1]/div[2]/div[1]/mat-dialog-container[1]/dialog-data-example-dialog[1]/div[1]/mat-tab-group[1]/mat-tab-header[1]/div[1]/div[1]/div[1]/div[2]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click()

Fast click on tab after dialog open - bug fast-click

Slow click on tab after dialog open - correct slow-click

Reproduction

Steps to reproduce:

  1. https://stackblitz.com/edit/angular-k1g4u3-pmsayf

Expected Behavior

Correctly loaded content of the newly selected tab

Actual Behavior

The empty content of the newly selected tab

Environment

  • Angular: 14.0.0
  • CDK/Material: 14.0.4
  • Browser(s): Google Chrome 103.0.5060.66
  • Operating System (e.g. Windows, macOS, Ubuntu): Windows

fildasabo avatar Jul 07 '22 06:07 fildasabo

Maybe there will be a problem in the animation. Because when I added [@.disabled]="true" animationDuration="0" to the mat-tab-group, the content is always rendered

Before - with empty content mat-tab-group

Then - everything is fine <mat-tab-group [@.disabled]="true" animationDuration="0">

Most important is [@.disabled]="true"

fildasabo avatar Jul 07 '22 07:07 fildasabo

I was able to reproduce on Chrome

Chrome/Chrome OS Version 102.0.5005.75 (Official Build) (64-bit)

zarend avatar Jul 08 '22 17:07 zarend

I spent some time debugging it and this seems like an issue either in the browser or in the Angular animations module, or some combination of both. I tried diffing the DOM between the broken and working states and it was identical, however for some reason the .mat-tab-body-content of the current tab has visibility: hidden, even though nothing is actually setting it. Even if I add visibility: visible !important through the dev tools, the element still doesn't render.

crisbeto avatar Jul 11 '22 07:07 crisbeto

@crisbeto I also tried to change the visibility manually using dev tools, and saw the same behavior. The problem for me was this rule:

.mat-mdc-tab-body-content[style*="visibility: hidden"] {
  display: none;
}

I was then able to show the content every time using the following override:

.mat-mdc-tab-body-content[style*="visibility: hidden"] {
  display: block !important;
}

My context for this bug is somewhat different. I am using a mat-tab under a mat-menu, but I think we are seeing the same issue due to the overlay. I see the behavior after closing and opening the mat-menu 2 times. Then changing the tab results in empty content.

I was able to workaround the issue, but lose animations by setting the animationDuration to 0 and overriding the styles:

Template:

<mat-menu #menu="matMenu">
  <mat-tab-group (click)="$event.stopPropagation()" animationDuration="0">
    <mat-tab label="1"> Content 1 </mat-tab>
    <mat-tab label="2"> Content 2 </mat-tab>
    <mat-tab label="3"> Content 3 </mat-tab>
  </mat-tab-group>
</mat-menu>

Styles (at the root aka styles.css):

.mat-mdc-tab-body-content[style*="visibility: hidden"] {
  display: block !important;
}

.mat-mdc-tab-body-content {
  visibility: visible !important;
}

Here is a stackblitz example with my workaround: https://stackblitz.com/edit/angular-umvjvd?file=src/app/menu-overview-example.html

There is a special note regarding the animation and visibility rule in https://github.com/angular/components/blob/main/src/material/tabs/tab-body.scss

Usually the visibility: hidden added by the animation is enough to prevent focus from entering the collapsed content, but children with their own visibility can override it. This is a fallback that completely hides the content when the element becomes hidden. Note that we can't do this in the animation definition, because the style gets recomputed too late, breaking the animation because Angular didn't have time to figure out the target height. This can also be achieved with JS, but it has issues when starting an animation before the previous one has finished.

joshuawwright avatar Dec 23 '22 20:12 joshuawwright

I'm using the latest angular but with legacy material components, and I have the same issue.

When the menu is first opened everything is great, but if u close it and open again the animation is bugged for the first time and then goes back to normal.

I tried to do your workaround but to no end :(

michaelparkadze avatar Jul 04 '23 13:07 michaelparkadze

+1

Brieg avatar Oct 11 '23 08:10 Brieg

+1

bobbhy avatar Oct 18 '23 12:10 bobbhy

+1

kburczyk avatar Nov 21 '23 08:11 kburczyk