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

Adding Portals to Menu Rendering #2398

Closed
a-type opened this issue Feb 23, 2018 · 1 comment
Closed

Adding Portals to Menu Rendering #2398

a-type opened this issue Feb 23, 2018 · 1 comment

Comments

@a-type
Copy link

a-type commented Feb 23, 2018

Feature addition

I have a WIP branch for this already to explore possibilities. The intention is to render the Menu component through a portal into document.body directly, or allow a user to specify their own element context. The Menu should be positioned absolutely within its parent element in such a way that its positioning is the same on the screen as it currently appears. The benefit of using a portal into a top-level element is that we 'escape' the overflow properties of the Select's parent elements, which have caused issues with many use cases (#810, #697, #637, #404, just from browsing).

gif

In the demo above, the Select itself is rendered directly within a div with overflow: hidden. The original Select would not render a visible menu at all. I have gotten it to the point of rendering a menu visibly, and optionally dynamically positioning that menu based on scroll position.

Proposed prop additions:

  • menuPopoutRenderContextElement: an HTMLElement or string (which must reference a DOM element id) which the user would like to be the parent of the popout menu on the page. This element must be absolutely positioned at (0,0) on the page for layout logic to work correctly, since the menu assumes it can absolutely position itself based on that origin.
  • menuPositionPollingInterval: the user can provide an interval, in ms, by which the Select should poll its own position and update the absolute position and width of the menu component while the menu is open. Polling is more or less the only simple and reliable way to refresh element scroll position, bounding box, and other required properties for rendering. Polling will only occur if the user provides this prop, and only while the menu is open. Default is 0, which will disable polling. When polling is disabled, the menu recalculates its position upon opening and remains in that position until closed. This will suffice for most use cases-- if a user tries to resize the window, for instance, the menu will lose focus and close anyway.

Proposed changes to data structures:

I'd like to modify MenuPlacement to include the absolute coordinates of the Select itself, and the width of the Select. These properties will be needed to position the Menu within an absolute context. New type definition:

export type Point = {
  top: number,
  left: number,
};
export type MenuAttachment = 'bottom' | 'top';
export type MenuPlacement = {
  attachment: MenuAttachment,
  anchor: Point,
  width: number,
};

Using top and left for Point so that it is clear that we are referring to a point with a coordinate system where Y is pixels from the top of the page. When the Menu is rendering in 'top' attachment mode, it must anchor its own bottom-left corner to this point. When Menu is rendering in 'bottom' attachment mode, it must anchor its own top-left corner to this point.

Proposed logic changes:

I've simplified the logic for calculating the ideal position for the menu (top or bottom) to only take the total available space into account and choose the larger side. This was necessitated because I no longer have a ref to the Menu itself when computing its position based on my changes. I could potentially find a way to refactor to provide a Menu ref to the calculating logic, but this may prove messy. This is primarily because I've moved the Menu positioning logic into a higher-order-component which wraps the entire Select component.

My WIP branch is present at https://github.com/a-type/react-select/tree/v2-portal-menu if you'd like to see the changes so far. I have the portal menu in a working but undocumented state. According to contribution guidelines, I'd like to pulse-check to see if this is a desired addition before completing documentation and submitting a PR.

@bladey
Copy link
Contributor

bladey commented May 27, 2020

Hello -

In an effort to sustain the react-select project going forward, we're closing old issues / pull requests.

We understand this might be inconvenient but in the best interest of supporting the broader community we have to direct our limited efforts to maintain the latest version.

If you feel this issue / pull request is still relevant and you'd like us to review it, please leave a comment and we'll do our best to get back to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants