UNPKG

@ozen-ui/kit

Version:

React component library

80 lines (79 loc) 3.45 kB
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]); }