quasar icon indicating copy to clipboard operation
quasar copied to clipboard

QMenu remains visible for scrolled out elements

Open eliaspanagiotidis opened this issue 1 year ago • 4 comments

What happened?

A QMenu linked to an element within a scroll area continues to stay visible even when the element is scrolled out of view, thereby obscuring other elements:

temp

What did you expect to happen?

The menu should either remain confined within the scroll area or become hidden upon scrolling. Adjusting the z-index does not appear to rectify the issue.

Reproduction URL

https://codepen.io/eliaspanagiotidis/pen/RwvjqYZ?editors=1010

How to reproduce?

Press the "Open menu" button to open the menu. Scroll up using the mouse (not the scrollbar).

Flavour

Quasar CLI with Vite (@quasar/cli | @quasar/app-vite)

Areas

Components (quasar)

Platforms/Browsers

No response

Quasar info output

No response

Relevant log output

No response

Additional context

No response

eliaspanagiotidis avatar Nov 16 '23 17:11 eliaspanagiotidis

The easiest solution that crosses my mind is to set the absolute position on the menu, this way it is going to stay attached to the element that triggered it. Another thing I assume might work is to use Intersection API which would allow to track if menu or the element that prompted it is no longer in a viewport and then close it.

thevladisss avatar Nov 17 '23 07:11 thevladisss

Thank you, @thevladisss. I’ve tried using absolute positioning, but it doesn’t seem to make a difference. The Intersection API could be a potential solution, but it has its drawbacks. Firstly, it might be excessive if multiple elements on a page are linked with QMenus. Secondly, it doesn’t completely solve the problem, especially when the element is near the top boundary of its container or partially hidden.

Currently, my workaround involves the following steps: When a QMenu is displayed (a) the "scrollTop" of the target element's first scrollable parent is stored and (b) a scroll event listener is added to the element (the event is removed when the QMenu is hidden). When a scroll event occurs, the current location is compared with the initial one. If the distance exceeds a certain threshold, the QMenu is hidden.

This method seems to work well, I’m wondering if there’s a simpler way to implement something similar directly in the QMenu.

eliaspanagiotidis avatar Nov 17 '23 08:11 eliaspanagiotidis

Thank you, @thevladisss. I’ve tried using absolute positioning, but it doesn’t seem to make a difference. The Intersection API could be a potential solution, but it has its drawbacks. Firstly, it might be excessive if multiple elements on a page are linked with QMenus. Secondly, it doesn’t completely solve the problem, especially when the element is near the top boundary of its container or partially hidden.

Currently, my workaround involves the following steps: When a QMenu is displayed (a) the "scrollTop" of the target element's first scrollable parent is stored and (b) a scroll event listener is added to the element (the event is removed when the QMenu is hidden). When a scroll event occurs, the current location is compared with the initial one. If the distance exceeds a certain threshold, the QMenu is hidden.

This method seems to work well, I’m wondering if there’s a simpler way to implement something similar directly in the QMenu.

Hi @eliaspanagiotidis. I've been thinking on your answer, and another suggestion I can have is to force the menu to position absolute which and use Intrsection API on the very menu, or to be more precise on its content. This would mean that if you open the menu and it is no longer in your viewport as it is absolute to its anchor element, it would would close self (in my example I d oits via ref and QMenu API).

This eliminates the problem with intersection API mentioned by you, as now it is not set onto the element that triggered the menu as there might be many.

thevladisss avatar Nov 18 '23 20:11 thevladisss

@thevladisss it seems you can't work on the QMenu content without hacks as it is handled internally by Quasar as a direct child of <body>.

From the manual:

Don’t worry about QMenu content inheriting CSS from the container as the QMenu will be injected as a direct child of <body> through a Quasar Portal.

eliaspanagiotidis avatar Nov 20 '23 09:11 eliaspanagiotidis