@spaced-out/ui-design-system
Version:
Sense UI components library
56 lines (42 loc) • 1.42 kB
Flow
// @flow strict
import {useEffect, useLayoutEffect, useState} from 'react';
type ReturnType = [boolean, (locked: boolean) => void];
export function useLockedBody(initialLocked: boolean = false): ReturnType {
const [locked, setLocked] = useState(initialLocked);
// Do the side effect before render
useLayoutEffect(() => {
if (!locked) {
return;
}
// Save initial body style
const originalOverflow = document.body?.style.overflow || '';
const originalPaddingRight = document.body?.style.paddingRight || '';
// Lock body scroll
if (document.body) {
document.body.style.overflow = 'hidden';
}
// Get the scrollBar width
// TODO(Nishant): Fetch the scrollBar width from the browser
const scrollBarWidth = 0;
// Avoid width reflow
if (!!scrollBarWidth && document.body) {
document.body.style.paddingRight = `${scrollBarWidth}px`;
}
return () => {
if (document.body) {
document.body.style.overflow = originalOverflow;
}
if (!!scrollBarWidth && document.body) {
document.body.style.paddingRight = originalPaddingRight;
}
};
}, [locked]);
// Update state if initialValue changes
useEffect(() => {
if (locked !== initialLocked) {
setLocked(initialLocked);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [initialLocked]);
return [locked, setLocked];
}