Modal API

API reference for the Modal component: its props with their token values and defaults, the styled-system prop groups, and forwarded HTML attributes.

Demos

For usage examples, visit the component demo page: Modal

Import

import { Modal } from '@soroush.tech/design-system/Modal'

Props

PropTypeDefaultDescription
isOpenboolean-If true, the modal is shown.
childrenReactNode-A single content element.
onClose(event, reason: 'escapeKey' | 'backdropClick') => void-Fired on Escape (top modal only) or backdrop click.
hasBackdropbooleantrueRender the dimmed backdrop.
shouldKeepMountedbooleanfalseKeep children mounted while closed.
shouldUsePortalbooleantruePortal the modal into portalContainer.
portalContainerHTMLElement | (() => HTMLElement | null) | nullbodyPortal target, or a function returning one.
shouldLockScrollbooleantrueLock body scroll while open.
shouldAutoFocusbooleantrueMove focus into the modal on open.
shouldTrapFocusbooleantrueTrap Tab focus within the modal.
shouldEnforceFocusbooleantruePull focus back into the modal whenever it escapes.
shouldRestoreFocusbooleantrueRestore focus to the trigger on close.
scroll'paper' | 'body'paperWhere long content scrolls. See below.
layer'appBar' | 'drawer' | 'modal'modalStacking layer, resolved from theme.zOrder.

The content element should carry its own dialog semantics (role="dialog", aria-modal, a label). Modal's root is role="presentation".


Scrolling long content

When content is too tall for the viewport, scroll controls where it scrolls:

  • scroll="paper" (default) - the root centres the content and it scrolls within the surface. Give your Paper a maxHeight and overflow="auto".
  • scroll="body" - the root itself is the scroll container. The surface keeps its natural height and the whole root (surface plus backdrop) scrolls. Short content is centred; tall content scrolls instead of clipping. Don't cap the surface height - use a margin for breathing room.

Example

const [isOpen, setIsOpen] = useState(false)

<Modal isOpen={isOpen} onClose={() => setIsOpen(false)}>
  <Paper role="dialog" aria-modal="true" aria-label="Settings" p={4}>
    <Typography variant="h5">Settings</Typography>
    <Button onClick={() => setIsOpen(false)}>Close</Button>
  </Paper>
</Modal>

Source code

If this page does not answer your question, have a look at the implementation of the component for more detail.