javascriptcssreactjsmaterial-uimakestyles

Pivotting a material UI dialog in the center of the screen when it's height may vary


I have an MUI Dialog, in which its height varies due to it being of a list that is filtered by the user. It ends up being annoying because the the dialog "jumps around" the screen trying to maintain it's center position as it grows and shrinks. This is what it looks like:

enter image description here

A simple solution for this particular issue would be simply to unset alignItems from the dialogPaper through the classes property. Something like this:

const useStyles = makeStyles((theme) => ({
  pivottedDialog: {
    alignItems: 'unset',
    ...
  },
}));

const MyDialog = () => (
  <Dialog
    {...otherProps}
    classes={{
      scrollPaper: classes.pivottedDialog
    }}
  >
    ...
  </Dialog>
)

This however, causes it to lose its centered positioning on the screen, when I do still need it to be centered (in reference to the dialog with the full list, without anything being filtered). I would like its starting point to be the same as the unchanged dialog, on all applicable screen sizes (above 600px of width)

enter image description here

How could I get this done?

I've tried to play around with the positioning and top property on the pivottedDialog class, but it changes depending on the screen size. This needs to be responsive and centered on all screen sizes above 600px width.

I made a sample app with the two dialogs, that can be played around with here: https://codesandbox.io/s/crazy-tesla-emc8m?file=/src/App.js


Solution

  • In this case. since the DialogContent height changes based upon the filter, I'd recommend setting a height and width for the Dialog and a height for the DialogContent.

    Working Demo:

    Edit Dynamic Filterable Material Modal

    Why is the content shifting? The problem comes from the fact that the Dialog uses a flex-blox (display: flex) that justifies the content to the center (justify-content: center) vertically (main-axis) and align items to the center (align-items: center) horizontally (cross-axis) in relation to the view port. This makes the center of the screen and the center of the Dialog box the reference points for how to align content.

    Are there any work-arounds? Yes, but they require a custom layout/custom modal. With a flexbox, you'd need something like the demo below to achieve a centered modal:

    Edit Dynamic Filterable Material Modal (no specified height)

    What this example demo does is creates a column with three rows and anchors the modal to the top of the second row:

     ___________________________
    |                           |
    |         Empty Row         |
    |      · 25% of view        |
    |___________________________|
    |   |------ Modal ------|   |
    |   |  · Top anchored   |   |
    |   |  · Expandable †   |   |
    |   |  · 50% of view    |   |
    |   |___________________|   |
    |                           |
    |                           |
    |                           |
    |___________________________|
    |                           |
    |         Empty Row         |
    |      · 25% of view        |
    |___________________________|
    

    † Modal can only expand to the max height of the row it resides within

    This allows the modal to shrink and grow while maintaining a vertical and horizontal center. The center won't be the center of the row because that would require the modal to shift vertically to compensate for the height change (which brings you back to the previous problem of content shifting).

    The disadvantages to this approach are that:

    The advantages to this approach are that:

    Which would be the best approach? The easiest and recommended solution is to just set a height/width on the modal. Another solution would be to use a filterable dropdown select list that won't affect the modal height.