@ozen-ui/kit
Version:
React component library
80 lines (79 loc) • 3.45 kB
JavaScript
import { useId } from 'react';
import { getScrollbarSize } from '../../utils/getScrollBarSize';
import { useIsomorphicEffect } from '../useIsomorphicEffect';
export var FIXED_CLASSNAME = 'ScrollLock-fixed';
var getPaddingRight = function (el) {
return parseInt(window.getComputedStyle(el).paddingRight, 10) || 0;
};
var lockIds = new Set();
var restoreStyleGlobal = { current: null };
export function useLockBodyScroll(active) {
if (active === void 0) { active = false; }
var lockId = useId();
var lockBody = function () {
var restoreStyle = [];
// Вычисляем все фиксированные элементы
var fixedBlocks = document.querySelectorAll(".".concat(FIXED_CLASSNAME));
// Получаем ширину полосы прокрутки
var paddingOffset = getScrollbarSize();
restoreStyle.push({
el: document.body,
value: document.body.style.overflow,
property: 'overflow',
});
// Блокируем полосу прокрутки
document.body.style.setProperty('overflow', 'hidden');
// Если прокрутки у body нет, то ничего не делаем
if (paddingOffset) {
// Получаем текущий отступ справа у элемента body
var originalPaddingRight = getPaddingRight(document.body);
restoreStyle.push({
el: document.body,
value: document.body.style.paddingRight,
property: 'padding-right',
});
// Назначаем body отступ равный ширине полосы прокрутки (учитываем текущий отступ body)
document.body.style.setProperty('padding-right', "".concat(originalPaddingRight + paddingOffset, "px"));
restoreStyle.push({
el: document.body,
value: '',
property: '--removed-body-scroll-bar-size',
});
document.body.style.setProperty('--removed-body-scroll-bar-size', "".concat(paddingOffset, "px"));
[].forEach.call(fixedBlocks, function (el) {
var originalPaddingRight = getPaddingRight(el);
restoreStyle.push({
el: el,
value: el.style.paddingRight,
property: 'padding-right',
});
el.style.setProperty('padding-right', "".concat(originalPaddingRight + paddingOffset, "px"));
});
}
restoreStyleGlobal.current = function () {
restoreStyle.forEach(function (_a) {
var el = _a.el, value = _a.value, property = _a.property;
el.style.setProperty(property, value || '');
});
};
};
useIsomorphicEffect(function () {
if (!active) {
return undefined;
}
var hasLock = lockIds.size > 0;
if (!hasLock) {
lockBody();
}
lockIds.add(lockId);
return function () {
var _a;
lockIds.delete(lockId);
if (lockIds.size > 0) {
return;
}
(_a = restoreStyleGlobal.current) === null || _a === void 0 ? void 0 : _a.call(restoreStyleGlobal);
restoreStyleGlobal.current = null;
};
}, [active]);
}