UNPKG

@razorpay/blade

Version:

The Design System that powers Razorpay

252 lines (247 loc) 11 kB
import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties'; import _defineProperty from '@babel/runtime/helpers/defineProperty'; import { FloatingOverlay, useFloating, FloatingPortal, FloatingFocusManager } from '@floating-ui/react'; import React__default from 'react'; import styled from 'styled-components'; import usePresence from 'use-presence'; import { drawerComponentIds } from './drawerComponentIds.js'; import { DrawerContext } from './DrawerContext.js'; import '../Box/BaseBox/index.js'; import '../../utils/index.js'; import '../../utils/assignWithoutSideEffects/index.js'; import { componentZIndices } from '../../utils/componentZIndices.js'; import { useDrawerStack } from './StackProvider.js'; import '../../utils/makeAccessible/index.js'; import '../../utils/metaAttribute/index.js'; import { useId } from '../../utils/useId.js'; import '../../utils/useVerifyAllowedChildren/index.js'; import '../../utils/makeAnalyticsAttribute/index.js'; import { mergeRefs } from '../../utils/useMergeRefs.js'; import { jsx, jsxs } from 'react/jsx-runtime'; import { BaseBox } from '../Box/BaseBox/BaseBox.web.js'; import { castWebType } from '../../utils/platform/castUtils.js'; import { makeMotionTime } from '../../utils/makeMotionTime/makeMotionTime.web.js'; import { useVerifyAllowedChildren } from '../../utils/useVerifyAllowedChildren/useVerifyAllowedChildren.js'; import useTheme from '../BladeProvider/useTheme.js'; import { metaAttribute } from '../../utils/metaAttribute/metaAttribute.web.js'; import { MetaConstants } from '../../utils/metaAttribute/metaConstants.js'; import { makeAnalyticsAttribute } from '../../utils/makeAnalyticsAttribute/makeAnalyticsAttribute.js'; import { makeAccessible } from '../../utils/makeAccessible/makeAccessible.web.js'; import { assignWithoutSideEffects } from '../../utils/assignWithoutSideEffects/assignWithoutSideEffects.js'; var _excluded = ["isOpen", "onDismiss", "zIndex", "children", "accessibilityLabel", "showOverlay", "initialFocusRef", "isLazy", "testID"]; 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; } var SHOW_DRAWER = 'show-drawer'; var AnimatedDrawerContainer = /*#__PURE__*/styled(BaseBox).withConfig({ displayName: "Drawerweb__AnimatedDrawerContainer", componentId: "sc-15ixhgr-0" })(function (_ref) { var theme = _ref.theme, isFirstDrawerInStack = _ref.isFirstDrawerInStack, isVisible = _ref.isVisible; var entranceTransition = "all ".concat(castWebType(castWebType(makeMotionTime(theme.motion.duration.xmoderate))), " ").concat(castWebType(theme.motion.easing.entrance)); var exitTransition = "all\n ".concat(castWebType(makeMotionTime(theme.motion.duration.moderate)), "\n ").concat(castWebType(theme.motion.easing.exit)); return { opacity: isVisible ? 1 : 0, transform: isVisible ? isFirstDrawerInStack ? 'translateX(calc(-100% - 16px))' : 'translateX(-100%)' : 'translateX(0%)', transition: isVisible ? entranceTransition : exitTransition, animationFillMode: 'initial' }; }); var DrawerOverlay = /*#__PURE__*/styled(FloatingOverlay).withConfig({ displayName: "Drawerweb__DrawerOverlay", componentId: "sc-15ixhgr-1" })(function (_ref2) { var theme = _ref2.theme; return _defineProperty({ opacity: 0, transition: "opacity\n ".concat(makeMotionTime(theme.motion.duration.xmoderate), "\n ").concat(castWebType(theme.motion.easing.exit)), backgroundColor: theme.colors.overlay.background.subtle }, "&.".concat(SHOW_DRAWER), { opacity: 1, transition: "opacity ".concat(makeMotionTime(theme.motion.duration.gentle), " ").concat(castWebType(theme.motion.easing.entrance)) }); }); var _Drawer = function _Drawer(_ref4, ref) { var isOpen = _ref4.isOpen, onDismiss = _ref4.onDismiss, _ref4$zIndex = _ref4.zIndex, zIndex = _ref4$zIndex === void 0 ? componentZIndices.drawer : _ref4$zIndex, children = _ref4.children, accessibilityLabel = _ref4.accessibilityLabel, _ref4$showOverlay = _ref4.showOverlay, showOverlay = _ref4$showOverlay === void 0 ? true : _ref4$showOverlay, initialFocusRef = _ref4.initialFocusRef, _ref4$isLazy = _ref4.isLazy, isLazy = _ref4$isLazy === void 0 ? true : _ref4$isLazy, testID = _ref4.testID, rest = _objectWithoutProperties(_ref4, _excluded); var closeButtonRef = React__default.useRef(null); var _React$useState = React__default.useState(zIndex), _React$useState2 = _slicedToArray(_React$useState, 2), zIndexState = _React$useState2[0], setZIndexState = _React$useState2[1]; useVerifyAllowedChildren({ children: children, componentName: 'Drawer', allowedComponents: [drawerComponentIds.DrawerHeader, drawerComponentIds.DrawerBody] }); var _useTheme = useTheme(), theme = _useTheme.theme; var drawerId = useId('drawer'); var _useDrawerStack = useDrawerStack(), drawerStack = _useDrawerStack.drawerStack, addToDrawerStack = _useDrawerStack.addToDrawerStack, removeFromDrawerStack = _useDrawerStack.removeFromDrawerStack; var _usePresence = usePresence(isOpen, { enterTransitionDuration: theme.motion.duration.gentle, exitTransitionDuration: theme.motion.duration.xmoderate, initialEnter: true }), isMounted = _usePresence.isMounted, isVisible = _usePresence.isVisible, isExiting = _usePresence.isExiting; var _React$useMemo = React__default.useMemo(function () { // eslint-disable-next-line @typescript-eslint/restrict-plus-operands var level = Object.keys(drawerStack).indexOf(drawerId) + 1; return { stackingLevel: level, isFirstDrawerInStack: level === 1 && Object.keys(drawerStack).length > 1 }; }, [drawerId, drawerStack]), stackingLevel = _React$useMemo.stackingLevel, isFirstDrawerInStack = _React$useMemo.isFirstDrawerInStack; var _useFloating = useFloating({ open: isMounted }), refs = _useFloating.refs, context = _useFloating.context; React__default.useEffect(function () { if (isOpen) { addToDrawerStack({ elementId: drawerId, onDismiss: onDismiss }); } else { removeFromDrawerStack({ elementId: drawerId }); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isOpen]); // When z-index is not defined by user, we use default drawer z index and add stackingLevel to ensure // new drawer that opens, always opens on top of previous one. React__default.useEffect(function () { // eslint-disable-next-line @typescript-eslint/restrict-plus-operands setZIndexState(zIndex + stackingLevel); // eslint-disable-next-line react-hooks/exhaustive-deps }, [isMounted]); var contextValue = React__default.useMemo(function () { return { close: onDismiss, closeButtonRef: closeButtonRef, stackingLevel: stackingLevel, isExiting: isExiting }; }, [isExiting, onDismiss, stackingLevel]); return /*#__PURE__*/jsx(DrawerContext.Provider, { value: contextValue, children: /*#__PURE__*/jsx(FloatingPortal, { children: isMounted || !isLazy ? /*#__PURE__*/jsx(FloatingFocusManager, { context: context, initialFocus: initialFocusRef !== null && initialFocusRef !== void 0 ? initialFocusRef : closeButtonRef, returnFocus: true, children: /*#__PURE__*/jsxs(BaseBox, _objectSpread(_objectSpread(_objectSpread({ display: isLazy ? undefined : isMounted ? 'block' : 'none', position: "fixed" }, metaAttribute({ name: MetaConstants.Drawer, testID: testID })), makeAnalyticsAttribute(rest)), {}, { zIndex: zIndexState, children: [showOverlay ? /*#__PURE__*/jsx(DrawerOverlay, _objectSpread({ onClick: function onClick() { onDismiss(); }, className: isVisible ? SHOW_DRAWER : '', lockScroll: true }, metaAttribute({ testID: 'drawer-overlay' }))) : null, /*#__PURE__*/jsx(AnimatedDrawerContainer, _objectSpread(_objectSpread({ isVisible: isVisible, isFirstDrawerInStack: isFirstDrawerInStack, width: { base: '90%', s: '375px', m: '420px' } }, makeAccessible({ role: 'dialog', modal: true, label: accessibilityLabel })), {}, { position: "fixed", top: "spacing.0", left: "100%", backgroundColor: "popup.background.subtle", elevation: "highRaised", height: "100%", display: "flex", flexDirection: "column", ref: mergeRefs(ref, refs.setFloating), onKeyDown: function onKeyDown(event) { if ((event === null || event === void 0 ? void 0 : event.key) === 'Escape' || (event === null || event === void 0 ? void 0 : event.code) === 'Escape') { onDismiss(); } }, children: children }))] })) }) : null }) }); }; /** * ### Drawer Component * * A drawer is a panel that slides in mostly from right side of the screen over the existing content in the viewport. * It helps in providing additional details or context and can also be used to promote product features or new products. * * --- * * #### Usage * * ```jsx const MyDrawer = () => { const [showDrawer, setShowDrawer] = React.useState(false); return ( <Box> <Button onClick={() => setShowDrawer(true)}>Open Drawer</Button> <Drawer isOpen={showDrawer} onDismiss={() => setShowDrawer(false)} > <DrawerHeader title="Announcements" /> <DrawerBody> <FTXAnnouncement /> <CatPictures /> </DrawerBody> <Drawer> </Box> ) } * ``` * * --- * * Checkout {@link https://blade.razorpay.com/?path=/docs/components-drawer Drawer Documentation} * * */ var Drawer = /*#__PURE__*/assignWithoutSideEffects( /*#__PURE__*/React__default.forwardRef(_Drawer), { displayName: 'Drawer', componentId: drawerComponentIds.Drawer }); export { Drawer }; //# sourceMappingURL=Drawer.web.js.map