@razorpay/blade
Version:
The Design System that powers Razorpay
139 lines (132 loc) • 6.15 kB
JavaScript
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import { useRef } from 'react';
import styled from 'styled-components';
import { useCollapsible } from './CollapsibleContext.js';
import { getTransitionDuration, getTransitionEasing, getOpacity, getCollapsibleBodyContentBoxProps } from './commonStyles.js';
import '../../utils/index.js';
import '../Box/index.js';
import { useDidUpdate } from '../../utils/useDidUpdate.js';
import '../Box/BaseBox/index.js';
import { jsx } from 'react/jsx-runtime';
import { BaseBox } from '../Box/BaseBox/BaseBox.web.js';
import { castWebType } from '../../utils/platform/castUtils.js';
import { makeSize } from '../../utils/makeSize/makeSize.js';
import { Box } from '../Box/Box.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; }
/**
* We can't animate to and from `auto` height, these are used for imperative css transitions.
* Overall on expanding height will change as: 0px -> Actual height -> auto
*/
var HEIGHT_EXPANDED = 'auto';
var HEIGHT_COLLAPSED = '0px';
var StyledCollapsibleBodyContent = /*#__PURE__*/styled(BaseBox).withConfig({
displayName: "CollapsibleBodyContentweb__StyledCollapsibleBodyContent",
componentId: "sc-1oi3ngc-0"
})(function (props) {
var theme = props.theme,
defaultIsExpanded = props.defaultIsExpanded,
isExpanded = props.isExpanded;
var transitionDuration = castWebType(getTransitionDuration(theme));
var transitionTimingFunction = castWebType(getTransitionEasing(theme));
return {
transitionDuration: transitionDuration,
transitionTimingFunction: transitionTimingFunction,
transitionProperty: 'height, opacity',
opacity: getOpacity({
isExpanded: isExpanded
}),
/**
* We need height explicitly here for initial styles because the component might be rendered on server,
* in which case for expanded items this should be `auto` because we don't know the actual pixel value.
*
* This is based on `defaultIsExpanded` rather than `isExpanded` because post initial render inline styles take over.
* Otherwise, changing `height` both here and in inline styles sometimes causes animation flickers due to styles mismatch.
*/
height: defaultIsExpanded ? HEIGHT_EXPANDED : HEIGHT_COLLAPSED,
display: defaultIsExpanded ? 'block' : 'none',
overflowY: 'hidden'
};
});
var CollapsibleBodyContent = function CollapsibleBodyContent(_ref) {
var children = _ref.children,
_hasMargin = _ref._hasMargin;
var _useCollapsible = useCollapsible(),
isExpanded = _useCollapsible.isExpanded,
defaultIsExpanded = _useCollapsible.defaultIsExpanded,
direction = _useCollapsible.direction;
var collapsibleBodyContentRef = useRef(null);
/**
* This effect imperatively updates height to make css transitions work:
* - for expanded items: auto height -> actual height -> 0px
* - for collapsed items: 0px -> actual height -> auto height
* - uses `requestAnimationFrame` to set the styles just before the next repaint
*/
useDidUpdate(function () {
var collapsibleBodyContentElement = collapsibleBodyContentRef.current;
if (!collapsibleBodyContentElement) {
return;
}
// In collapsed state display is set to none, change it back to block
collapsibleBodyContentElement.style.display = 'block';
var actualHeight = collapsibleBodyContentElement.scrollHeight;
if (!isExpanded) {
// collapse
requestAnimationFrame(function () {
collapsibleBodyContentElement.style.height = makeSize(actualHeight);
requestAnimationFrame(function () {
collapsibleBodyContentElement.style.height = makeSize(0);
});
});
} else {
// expand
requestAnimationFrame(function () {
collapsibleBodyContentElement.style.height = makeSize(0);
requestAnimationFrame(function () {
collapsibleBodyContentElement.style.height = makeSize(actualHeight);
/**
* After this we want to wait for the animation to finish
* before setting the height back to auto
*
* `onTransitionEnd` takes over
*/
});
});
}
}, [isExpanded]);
/**
* When expanding, waits for the animation to finish first.
* Then sets the height of expanded item to auto from actual height.
*/
var onTransitionEnd = function onTransitionEnd(_ref2) {
var propertyName = _ref2.propertyName;
var collapsibleBodyContentElement = collapsibleBodyContentRef.current;
if (propertyName === 'height' && collapsibleBodyContentElement) {
if (isExpanded) {
// Body content has expanded and finished animating at this point
requestAnimationFrame(function () {
collapsibleBodyContentElement.style.height = HEIGHT_EXPANDED;
});
} else {
// Body content has collapsed
requestAnimationFrame(function () {
collapsibleBodyContentElement.style.display = 'none';
});
}
}
};
return /*#__PURE__*/jsx(StyledCollapsibleBodyContent, {
ref: collapsibleBodyContentRef,
isExpanded: isExpanded,
defaultIsExpanded: defaultIsExpanded,
onTransitionEnd: onTransitionEnd,
children: /*#__PURE__*/jsx(Box, _objectSpread(_objectSpread({}, getCollapsibleBodyContentBoxProps({
direction: direction,
_hasMargin: _hasMargin
})), {}, {
children: children
}))
});
};
export { CollapsibleBodyContent };
//# sourceMappingURL=CollapsibleBodyContent.web.js.map