diff --git a/src/components/TopicDetail/TopicDetail.tsx b/src/components/TopicDetail/TopicDetail.tsx index 2cf8b0e42..2bdc29a71 100644 --- a/src/components/TopicDetail/TopicDetail.tsx +++ b/src/components/TopicDetail/TopicDetail.tsx @@ -30,6 +30,7 @@ import { GitHubIcon } from '../ReactIcons/GitHubIcon.tsx'; import { GoogleIcon } from '../ReactIcons/GoogleIcon.tsx'; import { YouTubeIcon } from '../ReactIcons/YouTubeIcon.tsx'; import { resourceTitleFromId } from '../../lib/roadmap.ts'; +import { lockBodyScroll } from '../../lib/dom.ts'; type TopicDetailProps = { resourceTitle?: string; @@ -262,6 +263,8 @@ export function TopicDetail(props: TopicDetailProps) { useEffect(() => { if (isActive) topicRef?.current?.focus(); + + lockBodyScroll(isActive); }, [isActive]); if (!isActive) { @@ -525,4 +528,4 @@ export function TopicDetail(props: TopicDetailProps) {
); -} +} \ No newline at end of file diff --git a/src/lib/dom.ts b/src/lib/dom.ts index a8acab84d..6d9fc1679 100644 --- a/src/lib/dom.ts +++ b/src/lib/dom.ts @@ -6,3 +6,14 @@ export function replaceChildren(parentNode: Element, newChild: Element) { parentNode.innerHTML = ''; parentNode.append(newChild); } + +export function lockBodyScroll(shouldLock: boolean) { + const isClient = document && 'body' in document; + if (!isClient) return; + + if (shouldLock) { + document.body.classList.add('overflow-hidden'); + } else { + document.body.classList.remove('overflow-hidden'); + } +} diff --git a/tailwind.config.cjs b/tailwind.config.cjs index 1471f04e7..d1301c24c 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -7,6 +7,7 @@ module.exports = { future: { hoverOnlyWhenSupported: true, }, + safelist: ['overflow-hidden'], theme: { extend: { typography: {