-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Fix dropdown menu position in playground when scroll #4496
Fix dropdown menu position in playground when scroll #4496
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, while this works it makes the Dropdown module lose it's reusability aspect as you're including the toolbar height in the computations.
We should be able to fix this retaining the position: fixed
and a transform: translate(x, y)
that moves as you scroll, looking at the nearest scroll parent and intersection (to handle visibility).
}: { | ||
children: React.ReactNode; | ||
dropDownRef: React.Ref<HTMLDivElement>; | ||
onClose: () => void; | ||
initialPosition: React.RefObject<number>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that dropdownRef should be sufficient to reposition accordingly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In some scenarios, our current setup falls short. Consider this: when a user opens the dropdown menu while the toolbar is already sticky at the top of the page, we only get 44px
as information. This doesn't tell us when the dropdown should start moving down the page as the user scrolls back up. So we need toolbar's initial position in order to solve that case. To figure out the toolbar's initial position, we need to capture this information right after the first render. That's why I'm proposing to pass in the initialPosition
.
Hello, I believe that in the useEffect(() => {
const button = buttonRef.current;
const dropDown = dropDownRef.current;
if (showDropDown && button !== null && dropDown !== null) {
const {top, left} = button.getBoundingClientRect();
dropDown.style.top = `${top + 40}px`;
dropDown.style.left = `${Math.min(
left,
window.innerWidth - dropDown.offsetWidth - 20,
)}px`;
}
}, [dropDownRef, buttonRef, showDropDown]); it is the useEffect hook in DropDown component and it is used for calculating the position of dropdown menu when it is shown, and 40 here is the height of toolbar. I can try to solve that as well if needed. I will also take a look at solving it using |
You're right
But do we need a strong dependency with the toolbar? My hunch is that we can build a component that is able to render a dropdown {above|before|after|below} a HTML ref. The dropdown should reposition when you scroll or resize the page to stick to the same position as the component is. |
Hello, I realized that the initial position is indeed unnecessary and I've been able to simplify the solution. The latest changes have been committed, where the dropdown component no longer depends on the button's height being set to 40px and can be accurately positioned in relation to the button element. I also took note of issue #4516 and concur that components such as dropdowns, modals, and buttons aren't central to a rich text editor framework. Until the core team settles on the direction to take - be it utilizing external libraries or developing in-house components - alterations to the playground code should be primarily directed towards rectifying existing bugs, instead of expanding the functionalities of current components. This PR is meant for a quick fix to improve the lexical playground user experience so I believe that addressing the dropdown's positioning within this very PR should suffice for the moment. |
Summary
This Pull Request introduces a fix to maintain the dropdown menu's position relative to the toolbar during page scroll. Previously, the dropdown menu was using
position: fixed
, causing it to remain stationary in the viewport instead of moving along with the toolbar during scrolling.How to reproduce
adding content in the playground editor untill a scroll bar appear, and then open any dropdown menu in the toolbar and scroll the page.
Details
The dropdown menu's positioning logic has been updated to become fixed or absolute based on the toolbar's position.
Important Note
Obtaining an accurate toolbar position is crucial for this logic. However, due to asynchronous loading of elements (like the Logo), directly extracting the toolbar's position in a
useEffect
hook can result in inaccurate values. To ensure precision, we're extracting the toolbar position asynchronously, which guarantees the correct calculation after all page elements have fully loaded. This is done by usingsetTimeout
which could be consider a bad paractise, so any advice on extracting the toolbar position without using it is very appreciated.