@razorpay/blade
Version:
The Design System that powers Razorpay
155 lines (146 loc) • 6.04 kB
JavaScript
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
import React__default from 'react';
import '../../utils/index.js';
import '../../utils/logger/index.js';
import { useScrollLock } from '../../utils/useScrollLock.js';
import { usePrevious } from '../../utils/usePrevious/usePrevious.js';
import { throwBladeError } from '../../utils/logger/logger.js';
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
/**
* Hook to delay the state change
*
* This is used to delay the active step change to allow for transitions to finish
* This prevents the popover's footer from changing it's JSX while it's transitioning
*/
function useDelayedState(initialState, delay) {
var _React$useState = React__default.useState(initialState),
_React$useState2 = _slicedToArray(_React$useState, 2),
delayedState = _React$useState2[0],
_setDelayedState = _React$useState2[1];
var timeoutRef = React__default.useRef(undefined);
React__default.useEffect(function () {
timeoutRef.current = window.setTimeout(function () {
_setDelayedState(initialState);
}, delay);
return function () {
window.clearTimeout(timeoutRef.current);
};
}, [delay, initialState]);
var setDelayedState = React__default.useCallback(function (newState) {
_setDelayedState(newState);
window.clearTimeout(timeoutRef.current);
}, []);
return [delayedState, setDelayedState];
}
/**
* Keep track of when we are transitioning between steps
*
* This is used to prevent the popover from jumping to the next step before animations are finished
*/
var useIsTransitioningBetweenSteps = function useIsTransitioningBetweenSteps(activeStep, transitionDelay) {
var prevActiveStep = usePrevious(activeStep);
var _React$useState3 = React__default.useState(false),
_React$useState4 = _slicedToArray(_React$useState3, 2),
isTransitioning = _React$useState4[0],
setIsTransitioning = _React$useState4[1];
// Keep track of when we are transitioning between steps
React__default.useEffect(function () {
if (prevActiveStep === undefined) return;
setIsTransitioning(true);
var timeout = setTimeout(function () {
setIsTransitioning(false);
}, transitionDelay);
return function () {
clearTimeout(timeout);
};
}, [prevActiveStep, transitionDelay]);
return isTransitioning;
};
// https://stackoverflow.com/questions/46795955/how-to-know-scroll-to-element-is-done-in-javascript
function smoothScroll(element, options) {
return new Promise(function (resolve) {
if (false) {
if (!(element instanceof Element)) {
throwBladeError({
moduleName: 'smoothScroll',
message: 'argument "element" must be an instance of Element'
});
}
}
var same = 0;
var lastPos = null;
var scrollOptions = _objectSpread({
behavior: 'smooth'
}, options);
element.scrollIntoView(scrollOptions);
requestAnimationFrame(check);
// eslint-disable-next-line consistent-return
function check() {
var newPos = element === null || element === void 0 ? void 0 : element.getBoundingClientRect().top;
if (newPos === lastPos) {
if (same++ > 2) {
return resolve(null);
}
} else {
same = 0;
lastPos = newPos;
}
requestAnimationFrame(check);
}
});
}
function useIntersectionObserver(elementRef, _ref) {
var _ref$threshold = _ref.threshold,
threshold = _ref$threshold === void 0 ? 0 : _ref$threshold,
_ref$root = _ref.root,
root = _ref$root === void 0 ? null : _ref$root,
_ref$rootMargin = _ref.rootMargin,
rootMargin = _ref$rootMargin === void 0 ? '0%' : _ref$rootMargin;
var _React$useState5 = React__default.useState(),
_React$useState6 = _slicedToArray(_React$useState5, 2),
entry = _React$useState6[0],
setEntry = _React$useState6[1];
var updateEntry = function updateEntry(_ref2) {
var _ref3 = _slicedToArray(_ref2, 1),
entry = _ref3[0];
setEntry(entry);
};
React__default.useEffect(function () {
var node = elementRef === null || elementRef === void 0 ? void 0 : elementRef.current; // DOM Ref
var hasIOSupport = !!window.IntersectionObserver;
if (!hasIOSupport || !node) return;
var observerParams = {
threshold: threshold,
root: root,
rootMargin: rootMargin
};
var observer = new IntersectionObserver(updateEntry, observerParams);
observer.observe(node);
return function () {
return observer.disconnect();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [elementRef === null || elementRef === void 0 ? void 0 : elementRef.current, JSON.stringify(threshold), root, rootMargin]);
return entry;
}
var useLockBodyScroll = function useLockBodyScroll(shouldLock) {
var scrollLockRef = useScrollLock({
enabled: true,
reserveScrollBarGap: true
});
React__default.useEffect(function () {
var lockRef = scrollLockRef.current;
if (shouldLock) {
lockRef.activate();
} else {
lockRef.deactivate();
}
return function () {
lockRef.deactivate();
};
}, [shouldLock, scrollLockRef]);
};
export { smoothScroll, useDelayedState, useIntersectionObserver, useIsTransitioningBetweenSteps, useLockBodyScroll };
//# sourceMappingURL=utils.js.map