@razorpay/blade
Version:
The Design System that powers Razorpay
76 lines (73 loc) • 2.87 kB
JavaScript
import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock-upgrade';
import React__default from 'react';
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-empty-function */
/**
* Modified from: https://github.com/stipsan/react-spring-bottom-sheet/blob/main/src/hooks/useScrollLock.tsx
* Handle scroll locking to ensure a good dragging experience on Android and iOS.
*
* On iOS the following may happen if scroll isn't locked:
* - When dragging the sheet the background gets dragged at the same time.
* - When dragging the page scroll is also affected, causing the drag to feel buggy and "slow".
*
* On Android it causes the chrome toolbar to pop down as you drag down, and hide as you drag up.
* When it's in between two toolbar states it causes the framerate to drop way below 60fps on
* the bottom sheet drag interaction.
*
* This hook does two things
* - Provides a imparative API to activate and deactivate the body scroll lock
* - And ensures the activation and deactivation doesn't happen twice for a single target
*/
function useScrollLock(_ref) {
var targetRef = _ref.targetRef,
enabled = _ref.enabled,
reserveScrollBarGap = _ref.reserveScrollBarGap;
var active = React__default.useRef(false);
// Imparative functions which users can call
var ref = React__default.useRef({
activate: function activate() {
throw new TypeError('Tried to activate scroll lock too early');
},
deactivate: function deactivate() {},
active: active
});
React__default.useEffect(function () {
// if it's disabled we just return NOOP, so the functions do nothing even if called.
if (!enabled) {
ref.current = {
activate: function activate() {},
deactivate: function deactivate() {},
active: active
};
return;
}
var target = targetRef ? targetRef.current : document.body;
active.current = false;
ref.current = {
activate: function activate() {
// if we are already active do nothig
if (active.current) return;
// if not, set the active=true so next time this is called we know it's true
active.current = true;
if (!target) return;
disableBodyScroll(target, {
allowTouchMove: function allowTouchMove(el) {
return el.closest('[data-body-scroll-lock-ignore]');
},
reserveScrollBarGap: reserveScrollBarGap
});
},
deactivate: function deactivate() {
// only deactivate if we are active
if (!active.current) return;
active.current = false;
if (!target) return;
enableBodyScroll(target);
},
active: active
};
}, [enabled, targetRef, reserveScrollBarGap]);
return ref;
}
export { useScrollLock };
//# sourceMappingURL=useScrollLock.js.map