@razorpay/blade
Version:
The Design System that powers Razorpay
232 lines (225 loc) • 10.2 kB
JavaScript
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