UNPKG

@razorpay/blade

Version:

The Design System that powers Razorpay

232 lines (225 loc) 10.2 kB
import _defineProperty from '@babel/runtime/helpers/defineProperty'; import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties'; import { Fragment, useState, forwardRef } from 'react'; import { StyledAlert } from './StyledAlert.js'; import '../Icons/index.js'; import '../../utils/index.js'; import '../../utils/metaAttribute/index.js'; import '../Box/styledProps/index.js'; import '../Button/IconButton/index.js'; import '../Box/BaseBox/index.js'; import '../Typography/index.js'; import '../Button/BaseButton/index.js'; import '../Link/BaseLink/index.js'; import '../BladeProvider/index.js'; import '../../utils/makeAccessible/index.js'; import '../../utils/makeAnalyticsAttribute/index.js'; import { jsx, jsxs } from 'react/jsx-runtime'; import { getPlatformType } from '../../utils/getPlatformType/getPlatformType.js'; import { BaseBox } from '../Box/BaseBox/BaseBox.web.js'; import CheckCircleIcon from '../Icons/CheckCircleIcon/CheckCircleIcon.js'; import AlertOctagonIcon from '../Icons/AlertOctagonIcon/AlertOctagonIcon.js'; import InfoIcon from '../Icons/InfoIcon/InfoIcon.js'; import AlertTriangleIcon from '../Icons/AlertTriangleIcon/AlertTriangleIcon.js'; import useTheme from '../BladeProvider/useTheme.js'; import { useBreakpoint } from '../../utils/useBreakpoint/useBreakpoint.js'; import { Text } from '../Typography/Text/Text.js'; import { castNativeType, castWebType } from '../../utils/platform/castUtils.js'; import BaseButton from '../Button/BaseButton/BaseButton.js'; import BaseLink from '../Link/BaseLink/BaseLink.js'; import { IconButton } from '../Button/IconButton/IconButton.js'; import CloseIcon from '../Icons/CloseIcon/CloseIcon.js'; import { makeAccessible } from '../../utils/makeAccessible/makeAccessible.web.js'; import { metaAttribute } from '../../utils/metaAttribute/metaAttribute.web.js'; import { MetaConstants } from '../../utils/metaAttribute/metaConstants.js'; import { getStyledProps } from '../Box/styledProps/getStyledProps.js'; import { makeAnalyticsAttribute } from '../../utils/makeAnalyticsAttribute/makeAnalyticsAttribute.js'; var _excluded = ["description", "title", "isDismissible", "onDismiss", "emphasis", "isFullWidth", "color", "actions", "testID", "icon"]; 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 isReactNative = getPlatformType() === 'react-native'; // Need extra wrappers on React Native only for alignment var CloseButtonWrapper = isReactNative ? BaseBox : Fragment; var intentIconMap = { positive: CheckCircleIcon, negative: AlertOctagonIcon, information: InfoIcon, neutral: InfoIcon, notice: AlertTriangleIcon }; var _Alert = function _Alert(_ref, ref) { var description = _ref.description, title = _ref.title, _ref$isDismissible = _ref.isDismissible, isDismissible = _ref$isDismissible === void 0 ? true : _ref$isDismissible, onDismiss = _ref.onDismiss, _ref$emphasis = _ref.emphasis, emphasis = _ref$emphasis === void 0 ? 'subtle' : _ref$emphasis, _ref$isFullWidth = _ref.isFullWidth, isFullWidth = _ref$isFullWidth === void 0 ? false : _ref$isFullWidth, _ref$color = _ref.color, color = _ref$color === void 0 ? 'neutral' : _ref$color, actions = _ref.actions, testID = _ref.testID, icon = _ref.icon, rest = _objectWithoutProperties(_ref, _excluded); var _useTheme = useTheme(), theme = _useTheme.theme; var _useBreakpoint = useBreakpoint({ breakpoints: theme.breakpoints }), matchedDeviceType = _useBreakpoint.matchedDeviceType; var _useState = useState(true), _useState2 = _slicedToArray(_useState, 2), isVisible = _useState2[0], setIsVisible = _useState2[1]; var isDesktop = matchedDeviceType === 'desktop'; var isMobile = !isDesktop; var Icon = icon !== null && icon !== void 0 ? icon : intentIconMap[color]; var iconOffset = 'spacing.1'; // certain special cases below needs special care for near perfect alignment if (isReactNative) { if (isFullWidth && !title) { iconOffset = 'spacing.1'; } else if (!isFullWidth && !title) { iconOffset = 'spacing.0'; } else if (!isFullWidth && title) { iconOffset = 'spacing.2'; } } else if (isMobile) { if (!isFullWidth && title) { iconOffset = 'spacing.2'; } else if (isFullWidth && !title) { iconOffset = 'spacing.2'; } } else if (isFullWidth) { iconOffset = 'spacing.1'; } var shouldCenterAlign = isFullWidth && !title; var alignment = 'flex-start'; if (!isFullWidth) alignment = 'flex-start'; if (shouldCenterAlign) alignment = 'center'; var leadingIcon = /*#__PURE__*/jsx(BaseBox, { display: "flex", alignSelf: alignment, marginTop: iconOffset, children: /*#__PURE__*/jsx(Icon, { color: emphasis === 'intense' ? 'surface.icon.staticWhite.normal' : "feedback.icon.".concat(color, ".").concat(emphasis === 'subtle' ? 'intense' : 'subtle'), size: "medium" }) }); var textColor = emphasis === 'intense' ? 'surface.text.staticWhite.normal' : 'surface.text.gray.subtle'; var _title = title ? /*#__PURE__*/jsx(BaseBox, { marginBottom: "spacing.2", children: /*#__PURE__*/jsx(Text, { color: textColor, size: "medium", weight: "semibold", children: title }) }) : null; var _description = /*#__PURE__*/jsx(BaseBox, { marginTop: title || isReactNative ? 'spacing.0' : 'spacing.1', children: /*#__PURE__*/jsx(Text, { color: textColor, size: "small", children: description }) }); var primaryAction = actions !== null && actions !== void 0 && actions.primary ? /*#__PURE__*/jsx(BaseBox, { marginRight: "spacing.5", display: isReactNative ? castNativeType('flex') : castWebType('inline-flex'), children: /*#__PURE__*/jsx(BaseButton, { size: "small", onClick: actions.primary.onClick, color: emphasis === 'intense' ? 'white' : color, variant: "secondary", children: actions.primary.text }) }) : null; var secondaryActionParams = actions !== null && actions !== void 0 && actions.secondary ? { onClick: actions.secondary.onClick } : null; /** * TS assumes only common properties to be present for `SecondaryAction` union type * We add a type guard that checks if href is present on secondary action: * - If yes, then TS can assume it to be `SecondaryActionLinkButton` (href being a required property) * - If no, then it would be `SecondaryActionButton` (and link properties wouldn't be needed) */ if (actions !== null && actions !== void 0 && actions.secondary && secondaryActionParams && 'href' in actions.secondary) { secondaryActionParams.href = actions.secondary.href; secondaryActionParams.target = actions.secondary.target; secondaryActionParams.rel = actions.secondary.rel; } var secondaryAction = actions !== null && actions !== void 0 && actions.secondary ? /*#__PURE__*/jsx(BaseBox, { marginRight: "spacing.4", display: isReactNative ? 'flex' : 'inline-flex', children: /*#__PURE__*/jsx(BaseLink, _objectSpread(_objectSpread({ size: "small", color: emphasis === 'intense' ? 'white' : color }, secondaryActionParams), {}, { children: actions.secondary.text })) }) : null; // For certain cases we wish to render actions inline with text content var showActionsHorizontal = isFullWidth && isDesktop; var actionsHorizontal = showActionsHorizontal && (primaryAction || secondaryAction) ? /*#__PURE__*/jsxs(BaseBox, { flexDirection: "row", alignItems: "center", children: [primaryAction, secondaryAction] }) : null; var actionsVertical = !showActionsHorizontal && (primaryAction || secondaryAction) ? /*#__PURE__*/jsxs(BaseBox, { marginTop: "spacing.4", flexDirection: "row", alignItems: "center", children: [primaryAction, secondaryAction] }) : null; var onClickDismiss = function onClickDismiss() { if (onDismiss) { onDismiss(); } setIsVisible(false); }; var closeButton = isDismissible ? /*#__PURE__*/jsx(CloseButtonWrapper, { children: /*#__PURE__*/jsx(IconButton, { accessibilityLabel: "Dismiss alert", onClick: onClickDismiss, emphasis: emphasis === 'intense' ? 'subtle' : 'intense', size: "large", icon: CloseIcon }) }) : null; var a11yProps = makeAccessible(_objectSpread({ // React Native doesn't has status as role role: isReactNative || color === 'negative' || color === 'notice' ? 'alert' : 'status' }, color === 'notice' && { liveRegion: 'polite' })); if (!isVisible) { return null; } return /*#__PURE__*/jsx(BaseBox, _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({ ref: ref }, a11yProps), metaAttribute({ name: MetaConstants.Alert, testID: testID })), getStyledProps(rest)), makeAnalyticsAttribute(rest)), {}, { children: /*#__PURE__*/jsxs(StyledAlert, { color: color, emphasis: emphasis, isFullWidth: isFullWidth, isDesktop: isDesktop, textAlign: 'left', children: [leadingIcon, /*#__PURE__*/jsxs(BaseBox, { flex: 1, paddingLeft: isFullWidth ? 'spacing.4' : 'spacing.3', paddingRight: showActionsHorizontal ? 'spacing.4' : 'spacing.2', children: [_title, _description, actionsVertical] }), actionsHorizontal, closeButton] }) })); }; var Alert = /*#__PURE__*/forwardRef(_Alert); export { Alert }; //# sourceMappingURL=Alert.js.map