Repository: mui/material-ui (TypeScript) — Feature

Issue:
[Modal] Implement disableScrollLock property
Is there any documentation regarding this functionality out there? I saw a mention of it in the modal api reference but can't find when/how to use it.


Discussion:
@fltonii We have no documentation about it as we are speaking. I'm not sure it's something that is worth mentioning in the API page of the modal. The only "valid" use case I have seen so far is around people bundling two versions of Material-UI, realizing that their modal logic isn't valid (as it can only have one top model normally). This issue can be "solved" with a global variable.

@mui-org/core-contributors What do you think of adding `@ignore` in the Modal prop-types to hide the existence of this entity to our users?
@oliviertassinari we are using this on my project to disable the overflow style change to body. It was causing a huge performance issue when opening and closing modals. Is there another way to do this?
@jeffshaver Do you know why it was causing a performance issue?
We could add a property for this.
@olivertassinari I'm not 100% sure. But after figuring out the style change on body was causing it, I thought it was probably that changing styles on body cause a reflow and repaint of everything.
I also need to be able to disableScrollLock. Sounds good with a property for this.
@Sojborg If you want to give it a shot, it shouldn't be harder than:
```diff
 --- a/packages/material-ui/src/Modal/Modal.js
+++ b/packages/material-ui/src/Modal/Modal.js
@@ -213,6 +213,7 @@ class Modal extends React.Component {
       disableEscapeKeyDown,
       disablePortal,
       disableRestoreFocus,
+      disableScrollLock,
       hideBackdrop,
       innerRef,
       keepMounted,
@@ -354,6 +355,10 @@ Modal.propTypes = {
    */
   disableRestoreFocus: PropTypes.bool,
   /**
+   * Disable the scroll lock behavior.
+   */
+  disableScrollLock: PropTypes.bool,
+  /**
    * If `true`, the backdrop is not rendered.
    */
   hideBackdrop: PropTypes.bool,
@@ -412,6 +417,7 @@ Modal.defaultProps = {
   disableEscapeKeyDown: false,
   disablePortal: false,
   disableRestoreFocus: false,
+  disableScrollLock: false,
   hideBackdrop: false,
   keepMounted: false,
   // Modals don't open on the server so this won't conflict with concurrent requests.
diff --git a/packages/material-ui/src/Modal/ModalManager.js b/packages/material-ui/src/Modal/ModalManager.js
index 0a381abb9..f6334de0e 100644
--- a/packages/material-ui/src/Modal/ModalManager.js
+++ b/packages/material-ui/src/Modal/ModalManager.js
@@ -75,10 +75,9 @@ function removeContainerStyle(data) {
  */
 class ModalManager {
   constructor(options = {}) {
-    const { hideSiblingNodes = true, handleContainerOverflow = true } = options;
+    const { hideSiblingNodes = true } = options;

     this.hideSiblingNodes = hideSiblingNodes;
-    this.handleContainerOverflow = handleContainerOverflow;

     // this.modals[modalIdx] = modal
     this.modals = [];
@@ -130,7 +129,7 @@ class ModalManager {
     const containerIdx = findIndexOf(this.data, item => item.modals.indexOf(modal) !== -1);
     const data = this.data[containerIdx];

-    if (!data.style && this.handleContainerOverflow) {
+    if (!data.style && !modal.props.disableScrollLock) {
       setContainerStyle(data);
     }
   }
@@ -150,7 +149,7 @@ class ModalManager {

     // If that was the last modal in a container, clean up the container.
     if (data.modals.length === 0) {
-      if (this.handleContainerOverflow) {
+      if (!data.style && !modal.props.disableScrollLock) {
         removeContainerStyle(data);
       }
```

Resolving patch:
diff --git a/docs/pages/api/modal.md b/docs/pages/api/modal.md
--- a/docs/pages/api/modal.md
+++ b/docs/pages/api/modal.md
@@ -39,6 +39,7 @@ This component shares many concepts with [react-overlays](https://react-bootstra
 | <span class="prop-name">disableEscapeKeyDown</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, hitting escape will not fire any callback. |
 | <span class="prop-name">disablePortal</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | Disable the portal behavior. The children stay within it's parent DOM hierarchy. |
 | <span class="prop-name">disableRestoreFocus</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the modal will not restore focus to previously focused element once modal is hidden. |
+| <span class="prop-name">disableScrollLock</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | Disable the scroll lock behavior. |
 | <span class="prop-name">hideBackdrop</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the backdrop is not rendered. |
 | <span class="prop-name">keepMounted</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | Always keep the children in the DOM. This prop can be useful in SEO situation or when you want to maximize the responsiveness of the Modal. |
 | <span class="prop-name">onBackdropClick</span> | <span class="prop-type">func</span> |  | Callback fired when the backdrop is clicked. |
diff --git a/docs/src/pages/components/modal/ServerModal.js b/docs/src/pages/components/modal/ServerModal.js
new file mode 100644
--- /dev/null
+++ b/docs/src/pages/components/modal/ServerModal.js
@@ -0,0 +1,51 @@
+import React from 'react';
+import { makeStyles } from '@material-ui/core/styles';
+import Modal from '@material-ui/core/Modal';
+
+const useStyles = makeStyles(theme => ({
+  root: {
+    transform: 'translateZ(0)',
+    height: 300,
+    flexGrow: 1,
+  },
+  modal: {
+    display: 'flex',
+    padding: theme.spacing(1),
+    alignItems: 'center',
+    justifyContent: 'center',
+  },
+  paper: {
+    width: 400,
+    backgroundColor: theme.palette.background.paper,
+    border: '2px solid #000',
+    boxShadow: theme.shadows[5],
+    padding: theme.spacing(2, 4, 4),
+  },
+}));
+
+export default function ServerModal() {
+  const classes = useStyles();
+  const rootRef = React.useRef(null);
+
+  return (
+    <div className={classes.root} ref={rootRef}>
+      <Modal
+        disablePortal
+        disableEnforceFocus
+        disableAutoFocus
+        open
+        aria-labelledby="server-modal-title"
+        aria-describedby="server-modal-description"
+        className={classes.modal}
+        container={() => rootRef.current}
+      >
+        <div className={classes.paper}>
+          <h2 id="server-modal-title">Server-side modal</h2>
+          <p id="server-modal-description">
+            You can disable the JavaScript, you will still see me.
+          </p>
+        </div>
+      </Modal>
+    </div>
+  );
+}
diff --git a/docs/src/pages/components/modal/ServerModal.tsx b/docs/src/pages/components/modal/ServerModal.tsx
new file mode 100644
--- /dev/null
+++ b/docs/src/pages/components/modal/ServerModal.tsx
@@ -0,0 +1,53 @@
+import React from 'react';
+import { makeStyles, Theme, createStyles } from '@material-ui/core/styles';
+import Modal from '@material-ui/core/Modal';
+
+const useStyles = makeStyles((theme: Theme) =>
+  createStyles({
+    root: {
+      transform: 'translateZ(0)',
+      height: 300,
+      flexGrow: 1,
+    },
+    modal: {
+      display: 'flex',
+      padding: theme.spacing(1),
+      alignItems: 'center',
+      justifyContent: 'center',
+    },
+    paper: {
+      width: 400,
+      backgroundColor: theme.palette.background.paper,
+      border: '2px solid #000',
+      boxShadow: theme.shadows[5],
+      padding: theme.spacing(2, 4, 4),
+    },
+  }),
+);
+
+export default function ServerModal() {
+  const classes = useStyles();
+  const rootRef = React.useRef<HTMLDivElement>(null);
+
+  return (
+    <div className={classes.root} ref={rootRef}>
+      <Modal
+        disablePortal
+        disableEnforceFocus
+        disableAutoFocus
+        open
+        aria-labelledby="server-modal-title"
+        aria-describedby="server-modal-description"
+        className={classes.modal}
+        container={() => rootRef.current}
+      >
+        <div className={classes.paper}>
+          <h2 id="server-modal-title">Server-side modal</h2>
+          <p id="server-modal-description">
+            You can disable the JavaScript, you will still see me.
+          </p>
+        </div>
+      </Modal>
+    </div>
+  );
+}
diff --git a/docs/src/pages/components/modal/SimpleModal.js b/docs/src/pages/components/modal/SimpleModal.js
--- a/docs/src/pages/components/modal/SimpleModal.js
+++ b/docs/src/pages/components/modal/SimpleModal.js
@@ -25,7 +25,6 @@ const useStyles = makeStyles(theme => ({
     border: '2px solid #000',
     boxShadow: theme.shadows[5],
     padding: theme.spacing(2, 4, 4),
-    outline: 'none',
   },
 }));
 
@@ -56,7 +55,7 @@ export default function SimpleModal() {
         onClose={handleClose}
       >
         <div style={modalStyle} className={classes.paper}>
-          <h2 id="modal-title">Text in a modal</h2>
+          <h2 id="simple-modal-title">Text in a modal</h2>
           <p id="simple-modal-description">
             Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
           </p>
diff --git a/docs/src/pages/components/modal/SimpleModal.tsx b/docs/src/pages/components/modal/SimpleModal.tsx
--- a/docs/src/pages/components/modal/SimpleModal.tsx
+++ b/docs/src/pages/components/modal/SimpleModal.tsx
@@ -26,7 +26,6 @@ const useStyles = makeStyles((theme: Theme) =>
       border: '2px solid #000',
       boxShadow: theme.shadows[5],
       padding: theme.spacing(2, 4, 4),
-      outline: 'none',
     },
   }),
 );
@@ -58,7 +57,7 @@ export default function SimpleModal() {
         onClose={handleClose}
       >
         <div style={modalStyle} className={classes.paper}>
-          <h2 id="modal-title">Text in a modal</h2>
+          <h2 id="simple-modal-title">Text in a modal</h2>
           <p id="simple-modal-description">
             Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
           </p>
diff --git a/docs/src/pages/components/modal/modal.md b/docs/src/pages/components/modal/modal.md
--- a/docs/src/pages/components/modal/modal.md
+++ b/docs/src/pages/components/modal/modal.md
@@ -34,6 +34,8 @@ Modal is a lower-level construct that is leveraged by the following components:
 
 {{"demo": "pages/components/modal/SimpleModal.js"}}
 
+Notice that you can disable the blue outline with the `outline: 0` CSS property.
+
 ## Performance
 
 The content of the modal is **lazily mounted** into the DOM.
@@ -85,16 +87,23 @@ Additionally, you may give a description of your modal with the `aria-describedb
 
 ```jsx
 <Modal
-  aria-labelledby="simple-modal-title"
-  aria-describedby="simple-modal-description"
+  aria-labelledby="modal-title"
+  aria-describedby="modal-description"
 >
   <h2 id="modal-title">
     My Title
   </h2>
-  <p id="simple-modal-description">
+  <p id="modal-description">
     My Description
   </p>
 </Modal>
 ```
 
 - The [WAI-ARIA Authoring Practices 1.1](https://www.w3.org/TR/wai-aria-practices/examples/dialog-modal/dialog.html) can help you set the initial focus on the most relevant element, based on your modal content.
+
+## Server-side modal
+
+React [doesn't support](https://github.com/facebook/react/issues/13097) the [`createPortal()`](https://reactjs.org/docs/portals.html) API on the server.
+In order to make it work, you need to disable this feature with the `disablePortal` prop:
+
+{{"demo": "pages/components/modal/ServerModal.js"}}
diff --git a/packages/material-ui/src/Modal/Modal.d.ts b/packages/material-ui/src/Modal/Modal.d.ts
--- a/packages/material-ui/src/Modal/Modal.d.ts
+++ b/packages/material-ui/src/Modal/Modal.d.ts
@@ -16,6 +16,7 @@ export interface ModalProps
   disableEscapeKeyDown?: boolean;
   disablePortal?: PortalProps['disablePortal'];
   disableRestoreFocus?: boolean;
+  disableScrollLock?: boolean;
   hideBackdrop?: boolean;
   keepMounted?: boolean;
   manager?: ModalManager;
diff --git a/packages/material-ui/src/Modal/Modal.js b/packages/material-ui/src/Modal/Modal.js
--- a/packages/material-ui/src/Modal/Modal.js
+++ b/packages/material-ui/src/Modal/Modal.js
@@ -22,15 +22,10 @@ function getHasTransition(props) {
   return props.children ? props.children.props.hasOwnProperty('in') : false;
 }
 
+// A modal manager used to track and manage the state of open Modals.
 // Modals don't open on the server so this won't conflict with concurrent requests.
 const defaultManager = new ModalManager();
 
-function getModal(modal, mountNodeRef, modalRef) {
-  modal.current.modalRef = modalRef.current;
-  modal.current.mountNode = mountNodeRef.current;
-  return modal.current;
-}
-
 export const styles = theme => ({
   /* Styles applied to the root element. */
   root: {
@@ -73,6 +68,7 @@ const Modal = React.forwardRef(function Modal(props, ref) {
     disableEscapeKeyDown = false,
     disablePortal = false,
     disableRestoreFocus = false,
+    disableScrollLock = false,
     hideBackdrop = false,
     keepMounted = false,
     manager = defaultManager,
@@ -93,9 +89,14 @@ const Modal = React.forwardRef(function Modal(props, ref) {
   const hasTransition = getHasTransition(props);
 
   const getDoc = () => ownerDocument(mountNodeRef.current);
+  const getModal = () => {
+    modal.current.modalRef = modalRef.current;
+    modal.current.mountNode = mountNodeRef.current;
+    return modal.current;
+  };
 
   const handleMounted = () => {
-    manager.mount(getModal(modal, mountNodeRef, modalRef));
+    manager.mount(getModal(), { disableScrollLock });
 
     // Fix a bug on Chrome where the scroll isn't initially 0.
     modalRef.current.scrollTop = 0;
@@ -104,7 +105,7 @@ const Modal = React.forwardRef(function Modal(props, ref) {
   const handleOpen = useEventCallback(() => {
     const resolvedContainer = getContainer(container) || getDoc().body;
 
-    manager.add(getModal(modal, mountNodeRef, modalRef), resolvedContainer);
+    manager.add(getModal(), resolvedContainer);
 
     // The element was already mounted.
     if (modalRef.current) {
@@ -112,6 +113,8 @@ const Modal = React.forwardRef(function Modal(props, ref) {
     }
   });
 
+  const isTopModal = React.useCallback(() => manager.isTopModal(getModal()), [manager]);
+
   const handlePortalRef = useEventCallback(node => {
     mountNodeRef.current = node;
 
@@ -123,7 +126,7 @@ const Modal = React.forwardRef(function Modal(props, ref) {
       onRendered();
     }
 
-    if (open) {
+    if (open && isTopModal()) {
       handleMounted();
     } else {
       ariaHidden(modalRef.current, true);
@@ -131,7 +134,7 @@ const Modal = React.forwardRef(function Modal(props, ref) {
   });
 
   const handleClose = React.useCallback(() => {
-    manager.remove(getModal(modal, mountNodeRef, modalRef));
+    manager.remove(getModal());
   }, [manager]);
 
   React.useEffect(() => {
@@ -148,11 +151,6 @@ const Modal = React.forwardRef(function Modal(props, ref) {
     }
   }, [open, handleClose, hasTransition, closeAfterTransition, handleOpen]);
 
-  const isTopModal = React.useCallback(
-    () => manager.isTopModal(getModal(modal, mountNodeRef, modalRef)),
-    [manager],
-  );
-
   if (!keepMounted && !open && (!hasTransition || exited)) {
     return null;
   }
@@ -316,6 +314,10 @@ Modal.propTypes = {
    * modal is hidden.
    */
   disableRestoreFocus: PropTypes.bool,
+  /**
+   * Disable the scroll lock behavior.
+   */
+  disableScrollLock: PropTypes.bool,
   /**
    * If `true`, the backdrop is not rendered.
    */
@@ -328,8 +330,6 @@ Modal.propTypes = {
   keepMounted: PropTypes.bool,
   /**
    * @ignore
-   *
-   * A modal manager used to track and manage the state of open Modals.
    */
   manager: PropTypes.object,
   /**
diff --git a/packages/material-ui/src/Modal/ModalManager.js b/packages/material-ui/src/Modal/ModalManager.js
--- a/packages/material-ui/src/Modal/ModalManager.js
+++ b/packages/material-ui/src/Modal/ModalManager.js
@@ -58,32 +58,30 @@ function findIndexOf(containerInfo, callback) {
   return idx;
 }
 
-function handleNewContainer(containerInfo) {
-  // We are only interested in the actual `style` here because we will override it.
-  const restoreStyle = {
-    overflow: containerInfo.container.style.overflow,
-    'padding-right': containerInfo.container.style.paddingRight,
-  };
-
-  const style = {
-    overflow: 'hidden',
-  };
-
+function handleContainer(containerInfo, props) {
+  const restoreStyle = {};
+  const style = {};
   const restorePaddings = [];
   let fixedNodes;
 
-  if (containerInfo.overflowing) {
-    const scrollbarSize = getScrollbarSize();
+  if (!props.disableScrollLock) {
+    restoreStyle.overflow = containerInfo.container.style.overflow;
+    restoreStyle['padding-right'] = containerInfo.container.style.paddingRight;
+    style.overflow = 'hidden';
 
-    // Use computed style, here to get the real padding to add our scrollbar width.
-    style['padding-right'] = `${getPaddingRight(containerInfo.container) + scrollbarSize}px`;
+    if (isOverflowing(containerInfo.container)) {
+      const scrollbarSize = getScrollbarSize();
 
-    // .mui-fixed is a global helper.
-    fixedNodes = ownerDocument(containerInfo.container).querySelectorAll('.mui-fixed');
-    [].forEach.call(fixedNodes, node => {
-      restorePaddings.push(node.style.paddingRight);
-      node.style.paddingRight = `${getPaddingRight(node) + scrollbarSize}px`;
-    });
+      // Use computed style, here to get the real padding to add our scrollbar width.
+      style['padding-right'] = `${getPaddingRight(containerInfo.container) + scrollbarSize}px`;
+
+      // .mui-fixed is a global helper.
+      fixedNodes = ownerDocument(containerInfo.container).querySelectorAll('.mui-fixed');
+      [].forEach.call(fixedNodes, node => {
+        restorePaddings.push(node.style.paddingRight);
+        node.style.paddingRight = `${getPaddingRight(node) + scrollbarSize}px`;
+      });
+    }
   }
 
   Object.keys(style).forEach(key => {
@@ -137,7 +135,6 @@ export default class ModalManager {
     // this.contaniners[containerIndex] = {
     //   modals: [],
     //   container,
-    //   overflowing,
     //   restore: null,
     // }
     this.contaniners = [];
@@ -169,7 +166,6 @@ export default class ModalManager {
     this.contaniners.push({
       modals: [modal],
       container,
-      overflowing: isOverflowing(container),
       restore: null,
       hiddenSiblingNodes,
     });
@@ -177,12 +173,12 @@ export default class ModalManager {
     return modalIndex;
   }
 
-  mount(modal) {
+  mount(modal, props) {
     const containerIndex = findIndexOf(this.contaniners, item => item.modals.indexOf(modal) !== -1);
     const containerInfo = this.contaniners[containerIndex];
 
     if (!containerInfo.restore) {
-      containerInfo.restore = handleNewContainer(containerInfo);
+      containerInfo.restore = handleContainer(containerInfo, props);
     }
   }
 
diff --git a/packages/material-ui/src/Modal/TrapFocus.js b/packages/material-ui/src/Modal/TrapFocus.js
--- a/packages/material-ui/src/Modal/TrapFocus.js
+++ b/packages/material-ui/src/Modal/TrapFocus.js
@@ -36,7 +36,7 @@ function TrapFocus(props) {
   // ⚠️ You may rely on React.useMemo as a performance optimization, not as a semantic guarantee.
   // https://reactjs.org/docs/hooks-reference.html#usememo
   React.useMemo(() => {
-    if (!open) {
+    if (!open || typeof window === 'undefined') {
       return;
     }
 
diff --git a/packages/material-ui/src/Portal/Portal.d.ts b/packages/material-ui/src/Portal/Portal.d.ts
--- a/packages/material-ui/src/Portal/Portal.d.ts
+++ b/packages/material-ui/src/Portal/Portal.d.ts
@@ -3,7 +3,7 @@ import { PortalProps } from '../Portal';
 
 export interface PortalProps {
   children: React.ReactElement;
-  container?: React.ReactInstance | (() => React.ReactInstance) | null;
+  container?: React.ReactInstance | (() => React.ReactInstance | null) | null;
   disablePortal?: boolean;
   onRendered?: () => void;
 }


Test patch:
diff --git a/packages/material-ui/src/Modal/Modal.test.js b/packages/material-ui/src/Modal/Modal.test.js
--- a/packages/material-ui/src/Modal/Modal.test.js
+++ b/packages/material-ui/src/Modal/Modal.test.js
@@ -804,4 +804,15 @@ describe('<Modal />', () => {
       mount(<TestCase />);
     });
   });
+
+  describe('prop: disablePortal', () => {
+    it('should render the content into the parent', () => {
+      const { container } = render(
+        <Modal open disablePortal>
+          <div />
+        </Modal>,
+      );
+      expect(container.querySelector('[role="document"]')).to.be.ok;
+    });
+  });
 });
diff --git a/packages/material-ui/src/Modal/ModalManager.test.js b/packages/material-ui/src/Modal/ModalManager.test.js
--- a/packages/material-ui/src/Modal/ModalManager.test.js
+++ b/packages/material-ui/src/Modal/ModalManager.test.js
@@ -29,7 +29,7 @@ describe('ModalManager', () => {
     const modal = {};
     const modalManager2 = new ModalManager();
     const idx = modalManager2.add(modal, container1);
-    modalManager2.mount(modal);
+    modalManager2.mount(modal, {});
     assert.strictEqual(modalManager2.add(modal, container1), idx);
     modalManager2.remove(modal);
   });
@@ -47,7 +47,7 @@ describe('ModalManager', () => {
 
     it('should add modal1', () => {
       const idx = modalManager.add(modal1, container1);
-      modalManager.mount(modal1);
+      modalManager.mount(modal1, {});
       assert.strictEqual(idx, 0, 'should be the first modal');
       assert.strictEqual(modalManager.isTopModal(modal1), true);
     });
@@ -71,7 +71,7 @@ describe('ModalManager', () => {
 
     it('should add modal2 2', () => {
       const idx = modalManager.add(modal2, container1);
-      modalManager.mount(modal2);
+      modalManager.mount(modal2, {});
       assert.strictEqual(idx, 2, 'should be the "third" modal');
       assert.strictEqual(modalManager.isTopModal(modal2), true);
       assert.strictEqual(
@@ -125,7 +125,7 @@ describe('ModalManager', () => {
 
       const modal = {};
       modalManager.add(modal, container1);
-      modalManager.mount(modal);
+      modalManager.mount(modal, {});
       assert.strictEqual(container1.style.overflow, 'hidden');
       assert.strictEqual(container1.style.paddingRight, `${20 + getScrollbarSize()}px`);
       assert.strictEqual(fixedNode.style.paddingRight, `${14 + getScrollbarSize()}px`);
@@ -138,7 +138,7 @@ describe('ModalManager', () => {
     it('should restore styles correctly if none existed before', () => {
       const modal = {};
       modalManager.add(modal, container1);
-      modalManager.mount(modal);
+      modalManager.mount(modal, {});
       assert.strictEqual(container1.style.overflow, 'hidden');
       assert.strictEqual(container1.style.paddingRight, `${20 + getScrollbarSize()}px`);
       assert.strictEqual(fixedNode.style.paddingRight, `${0 + getScrollbarSize()}px`);
@@ -168,11 +168,11 @@ describe('ModalManager', () => {
       const modal1 = {};
       const modal2 = {};
       modalManager.add(modal1, container3);
-      modalManager.mount(modal1);
+      modalManager.mount(modal1, {});
       expect(container3.children[0]).to.be.ariaHidden;
 
       modalManager.add(modal2, container4);
-      modalManager.mount(modal2);
+      modalManager.mount(modal2, {});
       expect(container4.children[0]).to.be.ariaHidden;
 
       modalManager.remove(modal2);
@@ -242,7 +242,7 @@ describe('ModalManager', () => {
       const modal = { modalRef: container2.children[0] };
 
       modalManager.add(modal, container2);
-      modalManager.mount(modal);
+      modalManager.mount(modal, {});
       expect(container2.children[0]).not.to.be.ariaHidden;
       modalManager.remove(modal, container2);
       expect(container2.children[0]).to.be.ariaHidden;
@@ -259,7 +259,7 @@ describe('ModalManager', () => {
       container2.appendChild(sibling2);
 
       modalManager.add(modal, container2);
-      modalManager.mount(modal);
+      modalManager.mount(modal, {});
       expect(container2.children[0]).not.to.be.ariaHidden;
       modalManager.remove(modal, container2);
       expect(container2.children[0]).to.be.ariaHidden;