20

I have a custom modal where I have 2 react-select components inside. The modal body is ready to auto scroll in case the content exceeds its size, but the react-select components dropdown open inside the modal with this overflow, which is what i am not looking for. Without overflow, it works fine.

I'm working with CSS Modules.

<div className={styles.modalBody}>
    {this.props.children}
</div>

.modalBody {
    padding: padding;
    flex: 1 1 auto;
    height: 45vh;
    max-height: 100%;
    overflow: auto;
}

<Select
    id={this.props.id}
    className={styles[this.props.selectType ? this.props.selectType : 'selectWhite']}
    classNamePrefix="select"
    name={this.props.name}
    value={selectedOption ? selectedOption : this.props.value}
    placeholder={this.props.placeholder}
    onChange={this.onChange}
    options={this.props.options}
    isDisabled={this.props.disabled}
    isSearchable={false}/>

How can I fix this? Thank you! :)

RCohen
  • 1,702
  • 10
  • 24
  • 44

3 Answers3

41

You want to look at the menuPortalTarget prop. There's a topic on this in the Advanced documentation, specifically with a modal example provided. Something like:

  <Select
    {...otherProps}
    menuPortalTarget={document.body} />
Steve -Cutter- Blades
  • 5,057
  • 2
  • 26
  • 40
  • Perfect solution. I also combined this with the `menuShouldScrollIntoView` prop as well. – gleng Apr 12 '23 at 14:13
  • This is a better answer https://stackoverflow.com/questions/57089251/react-select-can-not-overlay-react-modal – phildn Apr 24 '23 at 14:01
5

You can use Menu Position as fixed by setting the prop,which in turn makes your dropdown as position fixed as

<Select menuPosition="fixed" />
Ram
  • 451
  • 10
  • 18
0

A full example of how to display the select menu in a modal (I added comments at important lines and a step-by-step explanation below):

import React, { useRef } from 'react';
import Select from 'react-select';
import { Dialog } from '@mui/material';

const MyModal: React.FC = () => {
    const ref = useRef<HTMLDivElement>(null);

    return (
        <Dialog
            // ...
            ref={ref} // stores a ref to the DOM node of the modal component
        >
            <Select
                // ...
                menuPortalTarget={ref.current} // pass the ref to `Select` to portal the select menu to the given DOM node
                styles={{
                    menuPortal: defaultStyles => ({  
                        ...defaultStyles,
                        paddingBottom: '10px', // style the menu when it's portalled into the DOM node given to `menuPortalTarget`
                    }),
                }}
            />
        </Dialog>
    );
};

export default MyModal;

Step-by-step explanation:

  1. I create a ref with the React.useRef hook.
  2. I'm getting a reference of the Dialog component (which in this example is a MUI dialog component (but could be any other Modal component) via ref={ref}
  3. I pass that ref to react-select's Select component via menuPortalTarget={ref.current}.
  4. I had to customize the placement of the menu via paddingBottom: '10px', because the menu would appear a bit too high in my case. You might have to adjust this differently.

Further comments:

  • document.body didn't do the trick for me. The menu appeared behind the modal for me in this case.
  • Unfortunately the react-select portaling docs do not contain any example code, so I hope this example is helpful to you.
Andru
  • 5,954
  • 3
  • 39
  • 56
  • document.body didn't work for you because zIndex of your modal was higher than zIndex of menuPortal. It should be enough to set correct zIndex on menuPortal (same method like you set paddingBottom). – marxin Mar 18 '23 at 21:15