Skip to content

Commit

Permalink
Merge pull request #2456 from adevinta/fix-snackbar-dialog-focus-trap
Browse files Browse the repository at this point in the history
fix(dialog): do not close dialog when foreground elements are clicked
  • Loading branch information
Powerplex authored Oct 8, 2024
2 parents 3ea3e81 + 0f9b7c4 commit 12a0943
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
24 changes: 23 additions & 1 deletion packages/components/dialog/src/DialogContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@ export interface ContentProps extends RadixDialog.DialogContentProps, DialogCont

export const Content = forwardRef(
(
{ children, className, isNarrow = false, size = 'md', ...rest }: ContentProps,
{
children,
className,
isNarrow = false,
size = 'md',
onInteractOutside,
...rest
}: ContentProps,
ref: Ref<HTMLDivElement>
): ReactElement => {
const { setIsFullScreen } = useDialog()
Expand All @@ -33,6 +40,21 @@ export const Content = forwardRef(
isNarrow,
size,
})}
onInteractOutside={e => {
const isForegroundElement = (e.target as HTMLElement).closest('.z-toast, .z-popover')

/**
* The focus trap of the dialog applies `pointer-events-none` on the body of the page in the background, but
* some components with an higher z-index have `pointer-events-auto` applied on them to remain interactive and ignore the focust trap (ex: a Snackbar with actions).
*
* Clicking on the snackbar will be considered as an "outside click" and close the dialog. We want to prevent this.
*/
if (isForegroundElement) {
e.preventDefault()
}

onInteractOutside?.(e)
}}
{...rest}
>
{children}
Expand Down
17 changes: 16 additions & 1 deletion packages/components/drawer/src/DrawerContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export type DrawerContentProps = RadixDrawer.DialogContentProps & DrawerContentS

export const DrawerContent = forwardRef(
(
{ className, size = 'md', side = 'right', ...rest }: DrawerContentProps,
{ className, size = 'md', side = 'right', onInteractOutside, ...rest }: DrawerContentProps,
ref: Ref<HTMLDivElement>
) => (
<RadixDrawer.Content
Expand All @@ -18,6 +18,21 @@ export const DrawerContent = forwardRef(
side,
className,
})}
onInteractOutside={e => {
const isForegroundElement = (e.target as HTMLElement).closest('.z-toast, .z-popover')

/**
* The focus trap of the drawer applies `pointer-events-none` on the body of the page in the background, but
* some components with an higher z-index have `pointer-events-auto` applied on them to remain interactive and ignore the focust trap (ex: a Snackbar with actions).
*
* Clicking on the snackbar will be considered as an "outside click" and close the drawer. We want to prevent this.
*/
if (isForegroundElement) {
e.preventDefault()
}

onInteractOutside?.(e)
}}
{...rest}
/>
)
Expand Down

0 comments on commit 12a0943

Please sign in to comment.