primereact
primereact copied to clipboard
Menu: Not Positioned Properly Relative to Fixed Element
Describe the bug
Consider the code below. The important thing is that
- we have an element with a fixed position (i.e. CSS
position: fixed;), and - this contains an element which triggers a PrimeReact Menu to popup.
const menuRef = useRef<Menu>(null);
<FixedNavBar style={{position: 'fixed', top: '0'}}>
<a onClick={(event) => menuRef.current?.toggle(event)}> Click Me! </a>
<Menu
model={ myMenuModel }
ref={ menuRef }
popup
/>
</FixedNavBar>
The expectation is that whenever the Menu is opened, it always (if there is enough room) appears right below the item that triggered it, in this case, the anchor element. To achieve this, PrimeReact sets inline styles on the menu which absolutely position it relative to the document body. The issue is that these computed positions fail when the menu should be positioned relative to a fixed element like a navigation bar. In fact, they fail no matter how you set the appendTo property of the menu.
- On the one hand, say I set
appendTo={document.body}(the default), so that the menu appears outside of the fixed element. Then, if I scroll the window while the menu is open, the menu will move relative to the viewport while the navigation bar stays fixed (undesirable). - On the other hand, say I set
appendTo='self', so that the menu appears inside the fixed element. Then the position of the menu will depend on the window's vertical scroll position at the moment that the menu was opened.
This issue has actually already been raised, and, in my opinion, unjustifiably closed. It can be solved externally only with undesirable workarounds such as setting !important styles which override PrimeReact's inline styles.
Possible Solutions:
- add an attribute called
popupPositionwhich can take the valueabsoluteorfixed. If set toabsoluteuse the current implementation. If set tofixed, compute the position of thetargetRefrelative to the viewport, and then set the position of the menu relative to the viewport as well, withposition: fixed. - allow external customisation of the style property (for
position,top,left, etc.) so that they don't automatically get overridden by PrimeReact.
Reproducer
No response
PrimeReact version
10.6.2
React version
17.x
Language
TypeScript
Build / Runtime
Create React App (CRA)
Browser(s)
No response
Steps to reproduce the behavior
Take a look at the bug description.
Expected behavior
The menu should always appear right below the targetRef, even when working with fixed-position navigation bars.
PR is welcome if you want to study the code how it opens the menu?