react-elegant-ui
Version:
Elegant UI components, made by BEM best practices for react
58 lines • 1.83 kB
JavaScript
import { getScrollBarGap, isRootHTMLElement, setStyle } from './utils';
var locksRegistry = new Map();
function getLockState(node) {
return locksRegistry.get(node);
}
function setLockState(node, state) {
locksRegistry.set(node, state);
}
function clearLockState(node) {
locksRegistry.delete(node);
}
function hasStaticVerticalScroll(node) {
var overflowY = getComputedStyle(node).overflowY;
return /scroll/.test(overflowY);
}
function getScrollbarSize(node) {
var hasScrollbarRoot = isRootHTMLElement(node) && window.innerWidth - document.documentElement.clientWidth > 0;
var hasScrollbarNode = node.scrollHeight > node.clientHeight;
if (hasScrollbarRoot || hasScrollbarNode || hasStaticVerticalScroll(node)) {
return getScrollBarGap();
}
return 0;
}
/**
* Lock will add padding to container instead of scroll to avoid blinking
*/
export function lock(container) {
var state = getLockState(container);
if (state) {
state.count++;
return;
}
var scrollBarSize = getScrollbarSize(container);
var computedPaddingRight = parseInt(getComputedStyle(container).getPropertyValue('padding-right'), 10);
// NOTE: styles may be broken in future while unlocking if it will changed while locking
// so probably we should observe changes and rewrite it to return actual values by unlocking
var initialStyle = setStyle(container, {
paddingRight: "".concat(computedPaddingRight + scrollBarSize, "px"),
overflow: 'hidden',
overflowX: 'hidden',
overflowY: 'hidden'
});
setLockState(container, {
initialStyle: initialStyle,
count: 1
});
}
export function unlock(container) {
var state = getLockState(container);
if (!state) {
return;
}
state.count--;
if (state.count === 0) {
setStyle(container, state.initialStyle);
clearLockState(container);
}
}