diff --git a/src/components/Dialog/useBodyScrollLock.ts b/src/components/Dialog/BodyScrollSuppressor.tsx similarity index 50% rename from src/components/Dialog/useBodyScrollLock.ts rename to src/components/Dialog/BodyScrollSuppressor.tsx index 69a59e5d5f..5811c70d76 100644 --- a/src/components/Dialog/useBodyScrollLock.ts +++ b/src/components/Dialog/BodyScrollSuppressor.tsx @@ -1,6 +1,7 @@ -import { useEffect, useState } from 'react' +import React, { FC, useEffect, useState } from 'react' +import { createGlobalStyle, css } from 'styled-components' -export const useBodyScrollLock = () => { +export const BodyScrollSuppressor: FC = () => { const [scrollBarWidth, setScrollBarWidth] = useState(null) const [paddingRight, setPaddingRight] = useState(null) @@ -16,15 +17,21 @@ export const useBodyScrollLock = () => { setPaddingRight(scrollBarWidth + parseInt(originalPaddingRight, 10)) }, [scrollBarWidth]) - useEffect(() => { - if (paddingRight !== null) { - document.body.style.paddingInlineEnd = `${paddingRight}px` - } - document.body.style.overflow = 'hidden' - - return () => { - document.body.style.paddingInlineEnd = '' - document.body.style.overflow = '' - } - }, [paddingRight]) + if (scrollBarWidth === null) { + return null + } + return } + +const ScrollSuppressing = createGlobalStyle<{ + paddingRight: number | null +}>` + body { + overflow: hidden; + ${({ paddingRight }) => + paddingRight && + css` + padding-right: ${paddingRight}px !important; + `} + } +` diff --git a/src/components/Dialog/DialogContentInner.tsx b/src/components/Dialog/DialogContentInner.tsx index c67502ed78..1793b316b8 100644 --- a/src/components/Dialog/DialogContentInner.tsx +++ b/src/components/Dialog/DialogContentInner.tsx @@ -12,10 +12,10 @@ import { tv } from 'tailwind-variants' import { useHandleEscape } from '../../hooks/useHandleEscape' import { useTheme } from '../../hooks/useTailwindTheme' +import { BodyScrollSuppressor } from './BodyScrollSuppressor' import { DialogOverlap } from './DialogOverlap' import { DialogPositionProvider } from './DialogPositionProvider' import { FocusTrap } from './FocusTrap' -import { useBodyScrollLock } from './useBodyScrollLock' export type DialogContentInnerProps = PropsWithChildren<{ /** @@ -148,8 +148,6 @@ export const DialogContentInner: FC = ({ onClickOverlay && onClickOverlay() }, [isOpen, onClickOverlay]) - useBodyScrollLock() - return ( @@ -167,6 +165,8 @@ export const DialogContentInner: FC = ({ > {children} + {/* Suppresses scrolling of body while modal is displayed */} +