UNPKG

@razorpay/blade

Version:

The Design System that powers Razorpay

139 lines (132 loc) 6.15 kB
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