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
| Prop | Type | Default | Description |
|---|---|---|---|
isOpen | boolean | - | If true, the modal is shown. |
children | ReactNode | - | A single content element. |
onClose | (event, reason: 'escapeKey' | 'backdropClick') => void | - | Fired on Escape (top modal only) or backdrop click. |
hasBackdrop | boolean | true | Render the dimmed backdrop. |
shouldKeepMounted | boolean | false | Keep children mounted while closed. |
shouldUsePortal | boolean | true | Portal the modal into portalContainer. |
portalContainer | HTMLElement | (() => HTMLElement | null) | null | body | Portal target, or a function returning one. |
shouldLockScroll | boolean | true | Lock body scroll while open. |
shouldAutoFocus | boolean | true | Move focus into the modal on open. |
shouldTrapFocus | boolean | true | Trap Tab focus within the modal. |
shouldEnforceFocus | boolean | true | Pull focus back into the modal whenever it escapes. |
shouldRestoreFocus | boolean | true | Restore focus to the trigger on close. |
scroll | 'paper' | 'body' | paper | Where long content scrolls. See below. |
layer | 'appBar' | 'drawer' | 'modal' | modal | Stacking 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 yourPaperamaxHeightandoverflow="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.