Files
certd/packages/ui/certd-client/src/vben/composables/use-scroll-lock.ts
T

47 lines
1.4 KiB
TypeScript
Raw Normal View History

import { getScrollbarWidth, needsScrollbar } from "../shared/utils";
import { useScrollLock as _useScrollLock, tryOnBeforeUnmount, tryOnMounted } from "@vueuse/core";
export const SCROLL_FIXED_CLASS = `_scroll__fixed_`;
export function useScrollLock() {
const isLocked = _useScrollLock(document.body);
const scrollbarWidth = getScrollbarWidth();
tryOnMounted(() => {
if (!needsScrollbar()) {
return;
}
document.body.style.paddingRight = `${scrollbarWidth}px`;
const layoutFixedNodes = document.querySelectorAll<HTMLElement>(`.${SCROLL_FIXED_CLASS}`);
const nodes = [...layoutFixedNodes];
if (nodes.length > 0) {
2025-06-29 14:09:09 +08:00
nodes.forEach(node => {
node.dataset.transition = node.style.transition;
node.style.transition = "none";
node.style.paddingRight = `${scrollbarWidth}px`;
});
}
isLocked.value = true;
});
tryOnBeforeUnmount(() => {
if (!needsScrollbar()) {
return;
}
isLocked.value = false;
const layoutFixedNodes = document.querySelectorAll<HTMLElement>(`.${SCROLL_FIXED_CLASS}`);
const nodes = [...layoutFixedNodes];
if (nodes.length > 0) {
2025-06-29 14:09:09 +08:00
nodes.forEach(node => {
node.style.paddingRight = "";
requestAnimationFrame(() => {
node.style.transition = node.dataset.transition || "";
});
});
}
document.body.style.paddingRight = "";
});
}