Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug(MatTooltip): MatTooltip not work well with cdk-virtual-scroll-viewport #19365

Closed
trungphan opened this issue May 14, 2020 · 6 comments · Fixed by #19432
Closed

bug(MatTooltip): MatTooltip not work well with cdk-virtual-scroll-viewport #19365

trungphan opened this issue May 14, 2020 · 6 comments · Fixed by #19432
Assignees
Labels
area: cdk/scrolling area: material/tooltip G This is is related to a Google internal issue P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent

Comments

@trungphan
Copy link

Reproduction

Use StackBlitz to reproduce your issue: https://stackblitz.com/fork/components-issue

Steps to reproduce:

  1. Run this StackBlitz: https://stackblitz.com/edit/angular-1f53g9
  2. Click remove button for each row and the tooltips do not disappear.

Expected Behavior

What behavior were you expecting to see?
The tooltip needs to disappear when the row is removed

Actual Behavior

What behavior did you actually see?
The tooltip stay when a row is removed. This is likely similar to this issue: #6634 because the Angular CDK Virtual Scroller simply detach a view instead of removing it to reuse this view for other rows.

Environment

  • Angular:
  • CDK/Material:
  • Browser(s): Chrome
  • Operating System (e.g. Windows, macOS, Ubuntu): Mac OS
@trungphan trungphan added the needs triage This issue needs to be triaged by the team label May 14, 2020
@jelbourn jelbourn added G This is is related to a Google internal issue P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent and removed needs triage This issue needs to be triaged by the team labels May 14, 2020
@trungphan
Copy link
Author

Just an idea here. Can the MatTooltip use MutationObserver to know if the host element is removed from the dom, and hence remove itself?

@crisbeto
Copy link
Member

There are a couple of issues here: the first is the one you mentioned about the view being recycled, and the second is that our cleanup logic depends on the animation being finished. We have an event listener that's supposed to close tooltips on any body click, but they don't fire in this case, because the exit animation never starts.

Since we know how long the animation is supposed to take, we can add a fallback setTimeout that'll clear it if nothing happens within the expected time. The problem is that adding another timeout will probably break a lot of tests in g3. I gave it a quick try and it broke 5 of our own tests.

@trungphan
Copy link
Author

Instead of using setTimeout, what if you use another animation and listen for transition end event that is triggered slightly after the exit animation end event. This way, you can also easily debug animation by slowing it down and hopefully tests will also pass.

@crisbeto
Copy link
Member

The problem is that the view is detached from the change detection tree before the property that triggers the animation has even been changed so the transitionend won't fire in this case either. We could trigger the animation by directly changing a class in the DOM, then we'd have to refactor the tooltip so it doesn't use the Angular animations module which may break even more tests.

@trungphan
Copy link
Author

I'm guessing internally, the component uses Angular transition and I don't know much about Angular transition to comment. But for this particular case, a manual css transition could help you to detect if a DOM is removed. Specifically, the transitioncancel will be fired when the DOM is removed. Since the transitioncancel can be fired in some other cases, when the transitioncancel event fired, you can also verify that the element is not attached to the DOM or even generically if the element is not visible to the screen (e.g. display:none).

Also, if you have a code to check if an element is attached to the DOM, please make sure that it works shadow DOM since we're using shadow DOM.

All of theses sound complex, but I got a feeling that we may not even need to do all of these. It can be very simple: just when the transitioncancel or transitionend is fired, then remove the tooltip. That probably handles all cases.

@crisbeto crisbeto self-assigned this May 24, 2020
crisbeto added a commit to crisbeto/material2 that referenced this issue May 24, 2020
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger is destroyed or the exit animation has finished. The problem is that if the trigger is detached from change detection, but hasn't been destroyed, the exit animation will never run and the element won't be cleaned up. These changes switch to using CSS animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue May 24, 2020
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger is destroyed or the exit animation has finished. The problem is that if the trigger is detached from change detection, but hasn't been destroyed, the exit animation will never run and the element won't be cleaned up. These changes switch to using CSS animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue May 24, 2020
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger is destroyed or the exit animation has finished. The problem is that if the trigger is detached from change detection, but hasn't been destroyed, the exit animation will never run and the element won't be cleaned up. These changes switch to using CSS animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Jun 9, 2020
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger is destroyed or the exit animation has finished. The problem is that if the trigger is detached from change detection, but hasn't been destroyed, the exit animation will never run and the element won't be cleaned up. These changes switch to using CSS animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Jun 13, 2020
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger is destroyed or the exit animation has finished. The problem is that if the trigger is detached from change detection, but hasn't been destroyed, the exit animation will never run and the element won't be cleaned up. These changes switch to using CSS animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Jul 3, 2020
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger is destroyed or the exit animation has finished. The problem is that if the trigger is detached from change detection, but hasn't been destroyed, the exit animation will never run and the element won't be cleaned up. These changes switch to using CSS animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Aug 1, 2020
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger is destroyed or the exit animation has finished. The problem is that if the trigger is detached from change detection, but hasn't been destroyed, the exit animation will never run and the element won't be cleaned up. These changes switch to using CSS animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Aug 16, 2020
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger is destroyed or the exit animation has finished. The problem is that if the trigger is detached from change detection, but hasn't been destroyed, the exit animation will never run and the element won't be cleaned up. These changes switch to using CSS animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Oct 17, 2020
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Nov 20, 2020
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Nov 22, 2020
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue May 22, 2021
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue May 22, 2021
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Jun 18, 2021
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Jun 20, 2021
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Jun 20, 2021
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Jan 3, 2022
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Mar 5, 2022
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Mar 5, 2022
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Mar 5, 2022
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Mar 5, 2022
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Mar 5, 2022
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit to crisbeto/material2 that referenced this issue Mar 5, 2022
Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.
crisbeto added a commit that referenced this issue Mar 6, 2022
…19432)

* fix(material/tooltip): decouple removal logic from change detection

Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes #19365.

* fixup! fix(material/tooltip): decouple removal logic from change detection

(cherry picked from commit a5ab8e9)
crisbeto added a commit that referenced this issue Mar 6, 2022
…19432)

* fix(material/tooltip): decouple removal logic from change detection

Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes #19365.

* fixup! fix(material/tooltip): decouple removal logic from change detection
forsti0506 pushed a commit to forsti0506/components that referenced this issue Apr 3, 2022
…ngular#19432)

* fix(material/tooltip): decouple removal logic from change detection

Currently the logic in the tooltip that removes it from the DOM is run either if the trigger
is destroyed or the exit animation has finished. The problem is that if the trigger is
detached from change detection, but hasn't been destroyed, the exit animation will
never run and the element won't be cleaned up. These changes switch to using CSS
animations and manipulating the DOM node directly to trigger the animation.

Fixes angular#19365.

* fixup! fix(material/tooltip): decouple removal logic from change detection
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Apr 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: cdk/scrolling area: material/tooltip G This is is related to a Google internal issue P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants