UNPKG

@razorpay/blade

Version:

The Design System that powers Razorpay

324 lines (319 loc) 13.9 kB
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties'; import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; import _defineProperty from '@babel/runtime/helpers/defineProperty'; import React__default from 'react'; import '../Divider/index.js'; import '../Box/BaseBox/index.js'; import '../Typography/index.js'; import '../Button/IconButton/index.js'; import '../Icons/index.js'; import '../Box/index.js'; import '../../utils/assignWithoutSideEffects/index.js'; import '../../utils/isValidAllowedChildren/index.js'; import '../../utils/index.js'; import '../../utils/metaAttribute/index.js'; import '../../utils/logger/index.js'; import '../../tokens/global/index.js'; import '../../utils/makeAnalyticsAttribute/index.js'; import { jsxs, jsx } from 'react/jsx-runtime'; import { getComponentId } from '../../utils/isValidAllowedChildren/isValidAllowedChildren.js'; import { throwBladeError, logger } from '../../utils/logger/logger.js'; import { isReactNative } from '../../utils/platform/isReactNative.js'; import { BaseBox } from '../Box/BaseBox/BaseBox.web.js'; import { metaAttribute } from '../../utils/metaAttribute/metaAttribute.web.js'; import { makeAnalyticsAttribute } from '../../utils/makeAnalyticsAttribute/makeAnalyticsAttribute.js'; import { Box } from '../Box/Box.js'; import { IconButton } from '../Button/IconButton/IconButton.js'; import ChevronLeftIcon from '../Icons/ChevronLeftIcon/ChevronLeftIcon.js'; import { Text } from '../Typography/Text/Text.js'; import { makeSize } from '../../utils/makeSize/makeSize.js'; import { size } from '../../tokens/global/size.js'; import CloseIcon from '../Icons/CloseIcon/CloseIcon.js'; import { Divider } from '../Divider/Divider.js'; import { assignWithoutSideEffects } from '../../utils/assignWithoutSideEffects/assignWithoutSideEffects.js'; var _excluded = ["title", "subtitle", "leading", "titleSuffix", "trailing", "showDivider", "showBackButton", "showCloseButton", "onBackButtonClick", "onCloseButtonClick", "closeButtonRef", "backButtonRef", "testID", "onClickCapture", "onKeyDown", "onKeyUp", "onLostPointerCapture", "onPointerCancel", "onPointerDown", "onPointerMove", "onPointerUp", "metaComponentName", "paddingX", "marginY", "marginBottom", "marginTop", "size", "isDisabled", "children", "trailingInteractionElement"]; 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 commonCenterBoxProps = { display: 'flex', alignItems: 'center', justifyContent: 'center' }; var centerBoxProps = { large: _objectSpread(_objectSpread({}, commonCenterBoxProps), {}, { // We want to align title, icon, titleSuffix, trailing, closeButton to baseline // But we also want to keep them center aligned to each other // So we add a virtual Box around these slots with 28px and center align them to that box // We have done similar thing in figma as well (which is where this 28px comes from) height: '28px' }), medium: _objectSpread(_objectSpread({}, commonCenterBoxProps), {}, { height: '20px' }) }; var absolutePositionedButton = { position: 'absolute', top: 'spacing.0', right: 'spacing.0' }; var sizeTokensMapping = { large: { title: 'large' }, medium: { title: 'medium' } }; // prop restriction map for corresponding sub components var propRestrictionMap = { large: { Button: { size: 'xsmall', variant: 'tertiary' }, Badge: { size: 'medium' }, Link: { size: 'medium' }, Text: { size: 'medium', variant: 'body' }, Amount: { type: 'body', size: 'medium' } }, medium: { Button: { size: 'xsmall', variant: 'tertiary' }, Badge: { size: 'small' }, Link: { size: 'small' }, Text: { size: 'small', variant: 'body' }, Amount: { type: 'body', size: 'small' } } }; var useTrailingRestriction = function useTrailingRestriction(_ref) { var trailing = _ref.trailing, size = _ref.size; var _React$useState = React__default.useState(null), _React$useState2 = _slicedToArray(_React$useState, 2), validatedTrailingComponent = _React$useState2[0], setValidatedTrailingComponent = _React$useState2[1]; // validate and restrict sub component props in trailing prop React__default.useEffect(function () { if ( /*#__PURE__*/React__default.isValidElement(trailing)) { var trailingComponentType = getComponentId(trailing); var restrictedProps = propRestrictionMap[size][trailingComponentType]; var allowedComponents = Object.keys(propRestrictionMap[size]); if (false) { if (!restrictedProps) { throwBladeError({ message: "Only one of `".concat(allowedComponents.join(', '), "` component is accepted as trailing"), moduleName: 'Header' }); } } var restrictedPropKeys = Object.keys(propRestrictionMap[size][trailingComponentType]); for (var _i = 0, _restrictedPropKeys = restrictedPropKeys; _i < _restrictedPropKeys.length; _i++) { var _trailing$props; var prop = _restrictedPropKeys[_i]; if (trailing !== null && trailing !== void 0 && (_trailing$props = trailing.props) !== null && _trailing$props !== void 0 && _trailing$props.hasOwnProperty(prop)) { logger({ message: "Do not pass \"".concat(prop, "\" to \"").concat(trailingComponentType, "\" while inside Header trailing, because we override it."), moduleName: 'Header', type: 'warn' }); } } setValidatedTrailingComponent( /*#__PURE__*/React__default.cloneElement(trailing, restrictedProps)); } }, [trailing, size]); return validatedTrailingComponent; }; var _BaseHeader = function _BaseHeader(_ref2) { var title = _ref2.title, subtitle = _ref2.subtitle, leading = _ref2.leading, titleSuffix = _ref2.titleSuffix, trailing = _ref2.trailing, _ref2$showDivider = _ref2.showDivider, showDivider = _ref2$showDivider === void 0 ? true : _ref2$showDivider, _ref2$showBackButton = _ref2.showBackButton, showBackButton = _ref2$showBackButton === void 0 ? false : _ref2$showBackButton, _ref2$showCloseButton = _ref2.showCloseButton, showCloseButton = _ref2$showCloseButton === void 0 ? true : _ref2$showCloseButton, onBackButtonClick = _ref2.onBackButtonClick, onCloseButtonClick = _ref2.onCloseButtonClick, closeButtonRef = _ref2.closeButtonRef, backButtonRef = _ref2.backButtonRef, testID = _ref2.testID, onClickCapture = _ref2.onClickCapture, onKeyDown = _ref2.onKeyDown, onKeyUp = _ref2.onKeyUp, onLostPointerCapture = _ref2.onLostPointerCapture, onPointerCancel = _ref2.onPointerCancel, onPointerDown = _ref2.onPointerDown, onPointerMove = _ref2.onPointerMove, onPointerUp = _ref2.onPointerUp, metaComponentName = _ref2.metaComponentName, paddingX = _ref2.paddingX, marginY = _ref2.marginY, marginBottom = _ref2.marginBottom, marginTop = _ref2.marginTop, _ref2$size = _ref2.size, size$1 = _ref2$size === void 0 ? 'large' : _ref2$size, isDisabled = _ref2.isDisabled, children = _ref2.children, trailingInteractionElement = _ref2.trailingInteractionElement, rest = _objectWithoutProperties(_ref2, _excluded); var validatedTrailingComponent = useTrailingRestriction({ trailing: trailing, size: size$1 }); var shouldWrapTitle = titleSuffix && trailing && showBackButton && showCloseButton; var hasOnlyChildren = children && !(title || subtitle || titleSuffix || leading); var webOnlyEventHandlers = isReactNative() ? {} : { onClickCapture: onClickCapture, onKeyDown: onKeyDown, onKeyUp: onKeyUp, onLostPointerCapture: onLostPointerCapture, onPointerCancel: onPointerCancel, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerUp }; return /*#__PURE__*/jsxs(BaseBox, _objectSpread(_objectSpread(_objectSpread({}, metaAttribute({ name: metaComponentName, testID: testID })), makeAnalyticsAttribute(rest)), {}, { children: [/*#__PURE__*/jsxs(BaseBox, _objectSpread(_objectSpread({ marginY: marginY !== null && marginY !== void 0 ? marginY : { base: 'spacing.5', m: 'spacing.6' }, paddingX: paddingX !== null && paddingX !== void 0 ? paddingX : { base: 'spacing.5', m: 'spacing.6' }, marginTop: marginTop, marginBottom: marginBottom, touchAction: "none" }, webOnlyEventHandlers), {}, { children: [/*#__PURE__*/jsxs(BaseBox, { position: "relative", display: "flex", flexDirection: "row", userSelect: "none", children: [showBackButton ? /*#__PURE__*/jsx(BaseBox, { overflow: "visible", marginRight: "spacing.5", children: /*#__PURE__*/jsx(Box, _objectSpread(_objectSpread({}, centerBoxProps[size$1]), {}, { children: /*#__PURE__*/jsx(IconButton, { ref: backButtonRef, size: "large", icon: ChevronLeftIcon, onClick: function onClick() { return onBackButtonClick === null || onBackButtonClick === void 0 ? void 0 : onBackButtonClick(); }, accessibilityLabel: "Back" }) })) }) : null, hasOnlyChildren ? null : /*#__PURE__*/jsxs(BaseBox, { paddingRight: "spacing.5", marginRight: "auto", flex: "auto", display: "flex", flexDirection: "row", alignItems: "flex-start", children: [leading ? /*#__PURE__*/jsx(BaseBox, _objectSpread(_objectSpread({ marginRight: "spacing.3" }, centerBoxProps[size$1]), {}, { children: leading })) : null, /*#__PURE__*/jsxs(BaseBox, { flex: "auto", children: [/*#__PURE__*/jsxs(BaseBox // Explicitly setting maxWidth in React Native because text is not being wrapped properly when multiple fix width components are rendered in header // In web, flex containers seem to work a expected // @todo: resolve this if we figure out some better solution later , { maxWidth: isReactNative() && shouldWrapTitle ? '100px' : undefined, flexShrink: 0, display: "flex", flexDirection: "row", children: [title ? /*#__PURE__*/jsx(Text, { size: sizeTokensMapping[size$1].title, marginTop: makeSize(size['1']), weight: "semibold", color: isDisabled ? 'surface.text.gray.disabled' : 'surface.text.gray.normal', wordBreak: "break-word", children: title }) : null, titleSuffix && /*#__PURE__*/jsx(BaseBox, { marginLeft: "spacing.3", children: /*#__PURE__*/jsx(Box, _objectSpread(_objectSpread({}, centerBoxProps[size$1]), {}, { children: titleSuffix })) })] }), subtitle ? /*#__PURE__*/jsx(Text, { variant: "body", size: "small", weight: "regular", color: isDisabled ? 'surface.text.gray.disabled' : 'surface.text.gray.muted', children: subtitle }) : null] })] }), validatedTrailingComponent ? /*#__PURE__*/jsx(BaseBox, { marginRight: "spacing.5", children: /*#__PURE__*/jsx(Box, _objectSpread(_objectSpread({}, centerBoxProps[size$1]), {}, { children: validatedTrailingComponent })) }) : null, showCloseButton ? /*#__PURE__*/jsx(Box, _objectSpread(_objectSpread({}, hasOnlyChildren ? absolutePositionedButton : centerBoxProps[size$1]), {}, { children: /*#__PURE__*/jsx(IconButton, { ref: closeButtonRef, size: "large", icon: CloseIcon, accessibilityLabel: "Close", onClick: function onClick() { return onCloseButtonClick === null || onCloseButtonClick === void 0 ? void 0 : onCloseButtonClick(); } }) })) : null, trailingInteractionElement && !children ? /*#__PURE__*/jsx(Box, _objectSpread(_objectSpread({}, centerBoxProps[size$1]), {}, { children: trailingInteractionElement })) : null] }), /*#__PURE__*/jsxs(BaseBox, { display: "flex", width: "100%", flexDirection: "row", alignItems: "center", justifyContent: "space-between", children: [/*#__PURE__*/jsx(Box, { width: "100%", children: children }), trailingInteractionElement && children ? /*#__PURE__*/jsx(Box, _objectSpread(_objectSpread({ alignSelf: "flex-start" }, centerBoxProps[size$1]), {}, { children: trailingInteractionElement })) : null] })] })), showDivider ? /*#__PURE__*/jsx(Divider, {}) : null] })); }; var BaseHeader = /*#__PURE__*/assignWithoutSideEffects(_BaseHeader, { componentId: 'BaseHeader' }); export { BaseHeader }; //# sourceMappingURL=BaseHeader.js.map