Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a material-ui Modal scrollable

I've created a Modal and put some text in it describing my app and how to use it, but the text overflows the Modal and so the top and bottom of the text aren't visible. I'd like to make the component scrollable so that my text isn't running off the ends of the page.

// The styling for the modal
const styles = theme => ({
    paper: {
        position: 'absolute',
        width: theme.spacing.unit * 130,
        backgroundColor: theme.palette.background.paper,
        boxShadow: theme.shadows[5],
        padding: theme.spacing.unit * 4,
    },
});


function getModalStyle() {
    const top = 50
    const left = 50

    return {
        top: `${top}%`,
        left: `${left}%`,
        transform: `translate(-${top}%, -${left}%)`,
        overflow: "scroll"
    };
}
// The actual modal
<Modal
    aria-labelledby="simple-modal-title"
    aria-describedby="simple-modal-description"
    open={this.state.modalOpen}
    onClose={this.handleModalClose}
>
    <div style={getModalStyle()} className={classes.paper}>
        <MyLongTextComponent/>
    </div>
</Modal>

I'd like for this to have scroll functionality that's independent of the actual page behind it. I haven't found much help on the internet, so any pointers would be very helpful! Also, if a Modal is the wrong component to use in this situation, please let me know. I'm moderately new to React and material-ui, so if there's a better way I'd love to learn how.

like image 714
Jahziel Villasana Avatar asked Dec 27 '18 02:12

Jahziel Villasana


5 Answers

You need to use 'overflow = scroll' for modal style.

Below is example code to get scrollable material-ui modal. withStyles is used to apply style for modal in this example.

  • image example of material-ui scrollable
  • material-ui usage of withstyles

    const styles = theme => ({
      modalStyle1:{
        position:'absolute',
        top:'10%',
        left:'10%',
        overflow:'scroll',
        height:'100%',
        display:'block'
      }
    });
    <Modal open={this.state.open4} className={this.props.classes.modalStyle1}>
      <div>
        <Button size="small" color="primary" variant="contained" onClick={this.closeOrder}>
          Close
        </Button>
        {this.getPics()}
      </div>
    </Modal>
    
like image 146
yasir Avatar answered Oct 05 '22 21:10

yasir


You will have better luck using the Dialog component. Modal is a lower-level construct which Dialog leverages. You can find Dialog examples in the component demos section.

like image 36
Ryan Cogswell Avatar answered Oct 05 '22 22:10

Ryan Cogswell


I know this question had already been answered but I found the checked reply as not complete.

In order to make a proper Modal you will most likely want it to have a max height and to be divided in 3 main sections:

  • Header
  • Content
  • Footer (optional)

If you have a long list of element in the content (i.e. a form), setting overflow: 'scroll' to modal will lead to two main issues:

  • maxHeight will only be applied to container while the rest of the content will be still visible underneath
  • When the user will scroll, the header will also scroll out of sight

A closer-to-production example involving only header and content would then be:

const styles = theme => ({
  modal:{
    position:'absolute',
    top:'10%',
    left:'10%',
    overflow:'hidden',
    height:'100%',
    maxHeight: 500,
    display:'block'
  },
  header: {
    padding: '12px 0',
    borderBottom: '1px solid darkgrey'
  },
  content: {
    padding: 12,
    overflow: 'scroll'
  }
});

const { classes } = this.props
<Modal open={this.state.open}>
  <div className={classes.modal}>
    <div className={classes.heading}>
      <h4>Your Title here</h4>
    </div>

    <div className={classes.content}>
      <Button size="small" color="primary" variant="contained" onClick={this.closeOrder}>
        Close
      </Button>

      {this.getPics()}
    </div>    
  </div>
</Modal>

Beside being better formatted, this solution has also two main differences that solve the real-life issues explained above:

  • Modal has overflow: hidden, hiding everything outside its box
  • Content has overflow: scroll, which doesn't skyrocket the header away and it's what we are looking for

Hope this helps!

like image 29
Moleskine Avatar answered Oct 05 '22 21:10

Moleskine


For anyone looking for a quick answer to this, here's the solution I found:

<Modal
                open={open}
                onClose={handleClose}
                aria-labelledby="simple-modal-title"
                aria-describedby="simple-modal-description"
                style={{ overflow: 'scroll' }}
              >

       <div style={
       zIndex: 10,
       position: absolute,}>
{/*your content here*/}
       </div>

</Modal>

So only 2 simple steps...

  1. Make modal overflow scrollable

    <Modal
                 style={{ overflow: 'scroll' }}
               >
    
  2. Update styles for every direct child of the modal. You need to add these 2 attributes at least:

    <div style={
    zIndex: 10,
    position: absolute,}>
    

Then you can use css to reposition the content with the top or left properties, or customize the container as you want. No need to switch to the Dialog component to solve this.

like image 37
Luis Rodrigo Serrano Avatar answered Oct 05 '22 21:10

Luis Rodrigo Serrano


From the v5 docs, you want to use a Dialog instead of a Modal which has a scroll=body|paper prop.

Instead of using a modal with an overflow:auto with an enclosing <div/>:

<Modal open={contentOpened} style={{ overflow: "auto" }}>
  <div>
    <MyModalContent />
  </div>
</Modal>

use the cleaner <Dialog/>

<Dialog open={contentOpened} scroll="body">
  <MyModalContent />
</Dialog>

Read more on MUI scrolling-content dialogs here...

like image 34
Kwame Opare Asiedu Avatar answered Oct 05 '22 20:10

Kwame Opare Asiedu