Skip to content

Commit

Permalink
[@mantine/core] Modal: Fix issue when it was impossible to interact w…
Browse files Browse the repository at this point in the history
…ith scrollbars behind overlay (#2669)

If a modal has overflow set to outside, the overlay covers the scrollbar. This causes the modal to close by default if the scrollbar is clicked.

This fix moves the overlay outside the modal-inner container, removes the mousedown event from the overlay and instead puts an onClick handler onto the modal-inner div.

Event propagation is also stopped when clicking the modal itself so that clicking inside the modal won't close the modal. This should take care of any clickable components or components like MultiSelect that render outside the modal to work correctly.
  • Loading branch information
armanatz committed Oct 11, 2022
1 parent 820a913 commit 7ff9084
Showing 1 changed file with 51 additions and 47 deletions.
98 changes: 51 additions & 47 deletions src/mantine-core/src/Modal/Modal.tsx
Expand Up @@ -214,56 +214,13 @@ export function Modal(props: ModalProps) {
}}
>
{(transitionStyles) => (
<Box id={baseId} className={cx(classes.root, className)} {...others}>
<div
className={classes.inner}
onKeyDownCapture={(event) => {
const shouldTrigger =
(event.target as any)?.getAttribute('data-mantine-stop-propagation') !== 'true';
shouldTrigger && event.key === 'Escape' && closeOnEscape && onClose();
}}
ref={focusTrapRef}
>
<Paper<'div'>
className={classes.modal}
shadow={shadow}
p={padding}
radius={radius}
role="dialog"
aria-labelledby={titleId}
aria-describedby={bodyId}
aria-modal
tabIndex={-1}
style={transitionStyles.modal}
unstyled={unstyled}
>
{(title || withCloseButton) && (
<div className={classes.header}>
<Text id={titleId} className={classes.title}>
{title}
</Text>

{withCloseButton && (
<CloseButton
iconSize={16}
onClick={onClose}
aria-label={closeButtonLabel}
className={classes.close}
/>
)}
</div>
)}

<div id={bodyId} className={classes.body}>
{children}
</div>
</Paper>
<>
<Box id={baseId} className={cx(classes.root, className)} {...others}>
<div style={transitionStyles.overlay}>
<Overlay
className={classes.overlay}
sx={{ position: 'fixed' }}
zIndex={0}
onMouseDown={() => closeOnClickOutside && onClose()}
blur={overlayBlur}
color={
overlayColor ||
Expand All @@ -273,8 +230,55 @@ export function Modal(props: ModalProps) {
unstyled={unstyled}
/>
</div>
</div>
</Box>
<div
role="presentation"
className={classes.inner}
onClick={() => closeOnClickOutside && onClose()}
onKeyDown={(event) => {
const shouldTrigger =
(event.target as any)?.getAttribute('data-mantine-stop-propagation') !== 'true';
shouldTrigger && event.key === 'Escape' && closeOnEscape && onClose();
}}
ref={focusTrapRef}
>
<Paper<'div'>
className={classes.modal}
shadow={shadow}
p={padding}
radius={radius}
role="dialog"
aria-labelledby={titleId}
aria-describedby={bodyId}
aria-modal
tabIndex={-1}
style={transitionStyles.modal}
unstyled={unstyled}
onClick={(event) => event.stopPropagation()}
>
{(title || withCloseButton) && (
<div className={classes.header}>
<Text id={titleId} className={classes.title}>
{title}
</Text>

{withCloseButton && (
<CloseButton
iconSize={16}
onClick={onClose}
aria-label={closeButtonLabel}
className={classes.close}
/>
)}
</div>
)}

<div id={bodyId} className={classes.body}>
{children}
</div>
</Paper>
</div>
</Box>
</>
)}
</GroupedTransition>
</OptionalPortal>
Expand Down

0 comments on commit 7ff9084

Please sign in to comment.