React-select: Unable to apply custom-styles for top menu-portal element via CSS

Created on 8 Aug 2018  路  13Comments  路  Source: JedWatson/react-select

I'm using classNamePrefix="Select" prop to style inner elements from external css-file.
Everything works fine, except menuPortal element. It does not receive any specific className and when used in combination with menuPortalTarget={document.body} it's impossible to style that top element from portal via .Select__someElemName {}.

Currently only possible solution to add styles to menuPortal element is to use inline styles:

  <Select
    menuPortalTarget={document.body}
    styles={{
      menuPortal: styles => ({ ...styles, zIndex: 100 }) //  >= dialog's z-index
    }}
  />

The portal rendered in document.body has closest human-readable className Select__menu:
screenshot 2018-08-08 18 28 08

It would be good to have ability to add custom class-names to this menuPortal element, since it might be rendered outside of <Select/> component.

Please fix it and thanks for great job! 馃憤

issuenhancement issureviewed

Most helpful comment

A workaround is to add a placeholder in the dom for the react-select-portals and then to apply classes you want to it:

image

Then specify the portal to the portal placeholder:
image

All 13 comments

I have the same problem.
I'm handling z-index dynamically in scss files.
It would be great, to set classNamePrefix at first div
image

@ixrock @igoriok1994 I don't know if you ever found a work around for this issue, but I am using menuPortalTarget={document.body} so can target the portal <div> with the following (probably evil) CSS selector:

body > [class^="css-"] {
  border: 3px solid yellow;
}

A workaround is to add a placeholder in the dom for the react-select-portals and then to apply classes you want to it:

image

Then specify the portal to the portal placeholder:
image

A workaround is to add a placeholder in the dom for the react-select-portals and then to apply classes you want to it:

Thats nice :)
Btw, what syntax highlighting theme and editor you using? Looks good.

Hello -

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

We understand this might be inconvenient but in the best interest of supporting the broader community we have to direct our efforts towards the current major version.

If you aren't using the latest version of react-select please consider upgrading to see if it resolves any issues you're having.

However, if you feel this issue 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!

I would love for this to be fixed so I can use styled components here. Unfortunately the workaround above won't help, as I'm trying to use this in a component library and we therefore don't have control over the body part of the dom.

Any chance of re-opening this?

Thanks for the feedback @brentg5, we'll review the issue.

Thank you @bladey, much appreciated!

Specifically what I've been trying to do is use styled or the css prop from styled-components on the MenuPortal component so that I can set the z-index of the portal. When I try to add any css in that way, none of it makes its way through to the dom (the generated classname doesn't get put anywhere).

I think the original ask of this ticket should solve my problem--but even if it doesn't, it sounds like it would provide a nice way to manage the z-index of the portal.

Greetings @brentg5 ,

Just curious if you have tried using the styles api? It looks like menuPortal is a supported api style and the example even demonstrates using a custom zIndex

https://react-select.com/advanced#portaling

<Select
  styles={{ menuPortal: base => ({ ...base, zIndex: 9999 }) }} 
/>

In the interest of of clearing out stale issues, I will be closing this as both inactive and resolved. If there are any specific issues or concerns, please feel free to reply and we can continue conversation or re-open this if necessary.

@ebonow The styles API does let you put styles on the portal. However, I am trying to customize react-select with the components API, which takes a set of components and swaps them out wholesale during react-select's composition.

Where that comes into play with this issue is that most of the time you just want to slightly customize or add to the original component that you're replacing (in this case, the MenuPortal); in those cases your component that you pass as a prop is just a wrapper around the original component with a few things customized (in this case, the z-index). Unfortunately, the MenuPortal component appears to not take a className prop and apply it to its root HTMLElement, which prevents consumers from customizing this component in isolation.

Here's some example code that illustrates the problem:

// The class name "noWorkie" will not be applied to the MenuPortal's dom
const MyMenuPortal: typeof reactSelectComponents.MenuPortal = props => (
    <rsComponents.MenuPortal {...props} className={"noWorkie"} />
);

export const MySelect = () => (
    <ReactSelectCreatable
        components={{
            menuPortal: MyMenuPortal,
        }}
    />
);

The full context here is that I am re-exposing react-select's API to my consumers so that they can further customize MySelect, and we have embraced the components API due to it being incredibly flexible. Unfortunately, due to this bug, the MenuPortal component is pretty much incompatible with the components API, which puts me and my consumers in a tough spot if they want to customize it 馃檨

Thank you for looking into this issue!

You can use both a custom component and the styles api especially if you are only applying one or two styles. This should suffice for your needs for now.

However, I agree that this is inconsistent though as classNamePrefix does not apply a customized className reflective of its component, nor does it support innerProps.

Per the documentation:

If you provide the classNamePrefix prop to react-select, all inner elements will be given a className with the provided prefix.

Inner Props
All functional properties that the component needs are provided in innerProps which you must spread.

It seems reasonable that these could and should be included and even if className wasn't available, the default class-naming structure should be sufficient.

I will reopen this ticket and ask that we apply some changes to the menu-portal component in an existing refactor PR that is currently in review.

Yeah, I don't see any reason why MenuPlacer shouldn't have the typical classname prop. I made a separate PR for that (https://github.com/JedWatson/react-select/pull/4342) since I'm not sure that it fits in with the existing refactor PR that @ebonow referenced (https://github.com/JedWatson/react-select/pull/4333).

Was this page helpful?
0 / 5 - 0 ratings