You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

77 lines
2.5 KiB

"use client";
import { useCallback, useEffect, useRef } from "react";
import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler";
let activeSheetCount = 0;
let bodyHadDropdownClass = false;
let initialBodyOverflow = "";
let initialHtmlOverflow = "";
let initialAppShellOverflow = "";
let initialAppShellTouchAction = "";
let lockedAppShell: HTMLElement | null = null;
type SheetScrollLockOptions = {
onBack?: () => void;
};
export function useSheetScrollLock(
isOpen: boolean,
options: SheetScrollLockOptions = {},
) {
const { onBack } = options;
const onBackRef = useRef(onBack);
onBackRef.current = onBack;
// Register in the hardware-back handler stack so that Flutter's
// __habibHandleHardwareBackSync() closes the sheet instead of exiting the screen.
const handleHardwareBack = useCallback(() => {
if (onBackRef.current) {
onBackRef.current();
return true; // handled — sheet closed
}
return false;
}, []);
useHardwareBackHandler(handleHardwareBack, isOpen);
useEffect(() => {
if (!isOpen) return;
if (activeSheetCount === 0) {
bodyHadDropdownClass = document.body.classList.contains("dropdown-open");
initialBodyOverflow = document.body.style.overflow;
initialHtmlOverflow = document.documentElement.style.overflow;
lockedAppShell = document.querySelector<HTMLElement>(".app-shell");
initialAppShellOverflow = lockedAppShell?.style.overflowY ?? "";
initialAppShellTouchAction = lockedAppShell?.style.touchAction ?? "";
}
activeSheetCount += 1;
document.body.classList.add("dropdown-open");
document.body.classList.add("question-sheet-open");
document.body.style.overflow = "hidden";
document.documentElement.style.overflow = "hidden";
if (lockedAppShell) {
lockedAppShell.style.overflowY = "hidden";
lockedAppShell.style.touchAction = "none";
}
return () => {
activeSheetCount = Math.max(0, activeSheetCount - 1);
if (activeSheetCount === 0) {
document.body.style.overflow = initialBodyOverflow;
document.documentElement.style.overflow = initialHtmlOverflow;
if (lockedAppShell) {
lockedAppShell.style.overflowY = initialAppShellOverflow;
lockedAppShell.style.touchAction = initialAppShellTouchAction;
lockedAppShell = null;
}
if (!bodyHadDropdownClass) {
document.body.classList.remove("dropdown-open");
}
document.body.classList.remove("question-sheet-open");
}
};
}, [isOpen]);
}