The Material-UI Dialog Component With Every Prop Enabled and Explained (MUI v5)

The Material-UI Dialog component is used for giving the user important information and blocking application interaction until the message is acknowledged.

Interestingly, the component has far more props than the average MUI component: 19 props are listed in the docs. This is because the Dialog composition is complex (many layers of elements in the DOM), it has numerous transition and styling props, and it has two semi-unique props for handling events.

In this post I will set values for every prop and explain what is happening. I will also create a custom theme with a component override and new default prop values.

Material-UI Dialog component with all props enabled
Material-UI Dialog component with all props enabled

A Code Sandbox link with full React code is in the Resources section.

Material-UI Dialog Component DOM Elements

MUI Dialog DOM Composition
MUI Dialog DOM Composition

Before we dive into the Dialog props, we need to establish a basic understanding of the component. It is actually composed the following Material-UI components: a Backdrop, a Container (sort of), and Paper. These construct a Dialog component and should not be confused with the children components that can be passed such as DialogContent or DialogTitle.

We can see these components reflected in the DOM elements in the screenshot above. The combo of CSS class and tag each element is rendered with are what create ‘components’.

In the case of the Container, it has class .MuiDialog-container so it’s not exactly like a typical MUI container component.

Keep this structure in mind as we examine the props. The Paper and Backdrop props affect some of these compositional components.

MUI Dialog PaperComponent, PaperProps, Scroll, and BackdropComponent

The four props explained in this section affect the compositional components of the Dialog.

<Dialog
  //PaperComponent={"span"}
  PaperProps={{ sx: dialogColor }}
  scroll="body"
  BackdropComponent={styled(Backdrop, {
    name: "MuiModal",
    slot: "Backdrop",
    overridesResolver: (props, styles) => {
      return styles.backdrop;
    }
  })({
    zIndex: -1,
    backgroundColor: "rgb(65,105,225,0.5)"
  })}
/>

The PaperComponent prop changes what element is rendered in place of the Paper compositional component. In the screenshot in the section above, this is the div with class .MuiPaper-root. It is the primary containing component for the Dialog children and the default ‘Paper’ component adds nice elevation styling. However, this prop allows for other values to be passed in, i.e. passing span will render a span in the DOM. In my example I leave it as the default value.

PaperProps enables you to pass props directly to the Paper component (or whatever component you passed in for PaperComponent). This is commonly used for passing styling values, such as I did by passing { sx: dialogColor }. It could be used to pass handlers and any other prop supported by the Paper component.

The Dialog scroll prop changes where the scrollbar (or scrollbars) are rendered when the Dialog content exceeds the Dialog size. In my example, change the Dialog sx prop maxWidth to 100px to see the difference.

The practical difference with the scroll prop is that a value of 'body' puts the scrollbar on the wrapper of the Dialog, and not on any internal content. This is what I prefer. A value of ‘paper’ puts scrollbars on internal content (i.e. the DialogContent and DialogActions components).

The BackdropComponent prop allows you to pass in a custom Backdrop component. While this seems useful, a limitation (in my opinion) is that the custom component has to be passed in as ElementType. An example of this is the object type returned by the style API. I would strongly prefer to also be able to pass in a Backdrop component like so: <Backdrop /> with whatever props I want to add. Read more about MUI’s Backdrop component here.

MUI Dialog Transition Props, Sizing Props, and Styling

The next batch of props affect Dialog styling and UI behavior on entrance, exit, and more.

<Dialog
  //TransitionComponent
  TransitionProps={{
    onExited: () => {
      console.log(value);
    }
    // timeout: {
    //   enter: 1000,
    //   exit: 1000
    // }
  }}
  transitionDuration={{ enter: 1000, exit: 1000 }}
  maxWidth="xs"
  //fullScreen
  //fullWidth
  sx={{ "& .MuiDialog-paper": {minWidth: "75%", maxHeight: 500 } }}
/>

MUI Dialog TransitionComponent by default utilizes a third-party component for handling transitions. This prop requires a value of type ElementType. The default is dynamic and has great support. Read more about it here.

In the above link you will also find information about all default props available to the TransitionComponent. These can be passed in using TransitionProps. A few examples are onEnter, onExit, and timeout.

I used onExited, which is an event that takes place after onExit is completed. I simply used it for console logging, but the example in the MUI docs cleverly uses one of the events for focusing on a child component of the Dialog.

The transitionDuration prop is a simple way to pass in timing controls for different stages of animations. I could have accomplished the same thing through TransitionProps.timeout.

maxWidth is likely the most common sizing prop you will use. It can set maxWidth of the modal based on breakpoints in your theme. The fullWidth prop requires the modal to take up its maxWidth, and the fullScreen prop makes the modal take up the whole screen.

The two styling props available to Dialog are sx and classes. In MUI v5 you should use sx instead of classes. It is less verbose code, has access to MUI styling system functionality, and requires one less import. Take a look at the styling in the sx prop above and read more about the sx prop here.

MUI Dialog onBackdropClick, onClose, and disableEscapeKeyDown

There are a few event handlers that we need to be familiar with in order to use the Dialog to it’s fullest potential.

//state and functions
const [open, setOpen] = React.useState(false);
const handleClose = (
  event: {},
  reason: "backdropClick" | "escapeKeyDown"
) => {
  setOpen(false);
  console.log(reason);
};
const handleBackdropClick = () => {
  //these fail to keep the modal open
  event.stopPropagation();
  return false;
};

//JSX
<Dialog
  onClose={handleClose}
  onBackdropClick={handleBackdropClick}
  disableEscapeKeyDown
/>

The onClose handler is common to many popup components. However, the Dialog’s onClose has a second parameter that gives the reason for close. A click on the backdrop passes ‘backdropClick’ as the value, and pressing the escape key passes ‘escapeKeyDown’ as the value. A manual close, for example from a close button click, will pass nothing (undefined) for that parameter.

The onBackdropClick handler only passes the click event. I attempted to use this handler to disable close on Backdrop click but I was unsuccessful. Even using event.stopPropagation() failed. This handler seems to be a niche use case.

The disableEscapeKeyDown boolean does exactly what it says. It might be useful if you wanted to force the user to interact with the calls to action in the Dialog. However, as noted above the Dialog can still be closed through a Backdrop click.

Additional MUI Dialog Props

Perhaps the most important prop of all is the open prop. It’s value is usually maintained through the useState hook.

Other props available are ARIA props such as aria-describedby, aria-labelledby, and aria-label. In don’t usually have a labeling element associated with my Dialog components, so the only prop I used in this example is aria-label.

const [open, setOpen] = React.useState(false);

//JSX
<Dialog
  open={open}
  aria-label="input-dialog"
  //aria-describedby
  //aria-labelledby
/>

Resources

Code Sandbox Link

Here’s how to precisely size and position the Dialog component.

MUI Dialog Docs Examples

MUI Dialog Docs API

Share this post:

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.