Skip to content

Commit

Permalink
fix wrong behaviour for multiple Dialogs (#2821)
Browse files Browse the repository at this point in the history
  • Loading branch information
Malinicz authored Dec 4, 2024
1 parent e2e1a87 commit 3861845
Showing 1 changed file with 11 additions and 33 deletions.
44 changes: 11 additions & 33 deletions src/components/dialog/useBodyNoScroll.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';

const NO_SCROLL_CLASS = 'sg-dialog-no-scroll';
const DIALOG_SELECTOR = '.js-dialog';

export function useBodyNoScroll(overlayRef: {current: HTMLDivElement | null}) {
const cleanupRef = React.useRef(null);
Expand All @@ -11,47 +10,26 @@ export function useBodyNoScroll(overlayRef: {current: HTMLDivElement | null}) {
}, []);

React.useEffect(() => {
// @todo Use React Context API for detecting nested components
// https://github.com/brainly/style-guide/issues/2795
const isNestedDialog =
overlayRef.current?.parentElement?.closest(DIALOG_SELECTOR);

if (isNestedDialog) {
// if dialog is nested, this logic was already fired by parent dialog
// it prevents an issue with no cleanup when nested dialogs
return;
}

const body = document.body;
const scrollY = window.scrollY;

if (!body) return;
body.style.top = `-${scrollY}px`;

const initialBodyClassList = body.classList.value;
const initialBodyStyleTop = body.style.top;

if (initialBodyClassList.includes(NO_SCROLL_CLASS)) {
return;
}

body.style.top = `-${window.scrollY}px`;
body.classList.add(NO_SCROLL_CLASS);

const cleanup = () => {
// it can only be forced once
cleanupRef.current = null;

const dialogsOpenCount =
document.querySelectorAll(DIALOG_SELECTOR).length;
const nestedOpenDialogsCount =
// @ts-ignore TS2532
overlayRef.current?.querySelectorAll(DIALOG_SELECTOR).length | 0;

// nested dialogs shouldn't be counted
// as a parent for nested dialogs, this particular one should perfrom the cleanup
const notNestedDialogsOpenCount =
dialogsOpenCount - nestedOpenDialogsCount;

const manyDialogsOpened = notNestedDialogsOpenCount > 1;

if (manyDialogsOpened) {
return;
}

body.style.top = '';
body.classList.remove(NO_SCROLL_CLASS);
body.style.top = initialBodyStyleTop;
body.className = initialBodyClassList;
window.scrollTo(0, scrollY);
};

Expand Down

0 comments on commit 3861845

Please sign in to comment.