@kiwicom/orbit-components
Version:
Orbit-components is a React component library which provides developers with the easiest possible way of building Kiwi.com’s products.
261 lines (244 loc) • 10.3 kB
JavaScript
import * as React from "react";
import styled, { css } from "styled-components";
import { convertHexToRgba } from "@kiwicom/orbit-design-tokens";
import defaultTheme from "../defaultTheme";
import InformationCircle from "../icons/InformationCircle";
import Check from "../icons/Check";
import AlertTriangle from "../icons/Alert";
import AlertCircle from "../icons/AlertCircle";
import Close from "../icons/Close";
import ButtonLink from "../ButtonLink";
import { StyledTextLink, getLinkStyle } from "../TextLink";
import { TYPE_OPTIONS, TOKENS, CLOSE_BUTTON_DATA_TEST } from "./consts";
import { rtlSpacing, right, left } from "../utils/rtl";
import getSpacingToken from "../common/getSpacingToken";
import { Item } from "../List/ListItem";
import { StyledText } from "../Text";
import useTranslate from "../hooks/useTranslate";
import { StyledHeading } from "../Heading";
import media from "../utils/mediaQuery";
const getTypeToken = name => ({
theme,
type,
suppressed
}) => {
const tokens = {
[TOKENS.colorIconAlert]: {
[TYPE_OPTIONS.INFO]: theme.orbit.paletteBlueNormal,
[TYPE_OPTIONS.SUCCESS]: theme.orbit.paletteGreenNormal,
[TYPE_OPTIONS.WARNING]: theme.orbit.paletteOrangeNormal,
[TYPE_OPTIONS.CRITICAL]: theme.orbit.paletteRedNormal
},
[TOKENS.backgroundAlert]: {
[TYPE_OPTIONS.INFO]: suppressed ? theme.orbit.paletteCloudLight : theme.orbit.backgroundAlertInfo,
[TYPE_OPTIONS.SUCCESS]: suppressed ? theme.orbit.paletteCloudLight : theme.orbit.backgroundAlertSuccess,
[TYPE_OPTIONS.WARNING]: suppressed ? theme.orbit.paletteCloudLight : theme.orbit.backgroundAlertWarning,
[TYPE_OPTIONS.CRITICAL]: suppressed ? theme.orbit.paletteCloudLight : theme.orbit.backgroundAlertCritical
},
// TODO: create token
[TOKENS.colorTextLinkAlertHover]: {
[TYPE_OPTIONS.INFO]: theme.orbit.paletteBlueDarkHover,
[TYPE_OPTIONS.SUCCESS]: theme.orbit.paletteGreenDarkHover,
[TYPE_OPTIONS.WARNING]: theme.orbit.paletteOrangeDarkHover,
[TYPE_OPTIONS.CRITICAL]: theme.orbit.paletteRedDarkActive
},
// TODO: create token
[TOKENS.colorTextLinkAlertFocus]: {
[TYPE_OPTIONS.INFO]: convertHexToRgba(theme.orbit.paletteBlueDarkHover, 10),
[TYPE_OPTIONS.SUCCESS]: convertHexToRgba(theme.orbit.paletteGreenDarkHover, 10),
[TYPE_OPTIONS.WARNING]: convertHexToRgba(theme.orbit.paletteOrangeDarkHover, 10),
[TYPE_OPTIONS.CRITICAL]: convertHexToRgba(theme.orbit.paletteRedDarkActive, 10)
},
[TOKENS.colorBorderAlert]: {
[TYPE_OPTIONS.INFO]: suppressed ? theme.orbit.paletteCloudDark : theme.orbit.paletteBlueLightHover,
[TYPE_OPTIONS.SUCCESS]: suppressed ? theme.orbit.paletteCloudDark : theme.orbit.paletteGreenLightHover,
[TYPE_OPTIONS.WARNING]: suppressed ? theme.orbit.paletteCloudDark : theme.orbit.paletteOrangeLightHover,
[TYPE_OPTIONS.CRITICAL]: suppressed ? theme.orbit.paletteCloudDark : theme.orbit.paletteRedLightHover
},
[TOKENS.colorAccentBorder]: {
[TYPE_OPTIONS.INFO]: theme.orbit.paletteBlueNormal,
[TYPE_OPTIONS.SUCCESS]: theme.orbit.paletteGreenNormal,
[TYPE_OPTIONS.WARNING]: theme.orbit.paletteOrangeNormal,
[TYPE_OPTIONS.CRITICAL]: theme.orbit.paletteRedNormal
}
};
return tokens[name][type];
};
const StyledIcon = styled(({
icon,
type,
className
}) => {
// Icon should be boolean and TRUE
if (typeof icon === "boolean" && icon) {
if (type === TYPE_OPTIONS.INFO) {
return /*#__PURE__*/React.createElement(InformationCircle, {
className: className,
size: "small"
});
}
if (type === TYPE_OPTIONS.SUCCESS) {
return /*#__PURE__*/React.createElement(Check, {
className: className,
size: "small"
});
}
if (type === TYPE_OPTIONS.WARNING) {
return /*#__PURE__*/React.createElement(AlertTriangle, {
className: className,
size: "small"
});
}
if (type === TYPE_OPTIONS.CRITICAL) {
return /*#__PURE__*/React.createElement(AlertCircle, {
className: className,
size: "small"
});
}
}
if ( /*#__PURE__*/React.isValidElement(icon)) {
return /*#__PURE__*/React.cloneElement(icon, {
className,
size: "small"
});
}
return icon;
}).withConfig({
displayName: "Alert__StyledIcon",
componentId: "sc-1fh23bc-0"
})([""]);
const StyledDiv = ({
className,
children,
dataTest
}) => /*#__PURE__*/React.createElement("div", {
className: className,
"data-test": dataTest
}, children);
const StyledAlert = styled(StyledDiv).withConfig({
displayName: "Alert__StyledAlert",
componentId: "sc-1fh23bc-1"
})(["", ""], ({
theme,
closable
}) => css(["position:relative;display:flex;width:100%;border-radius:", ";border:1px solid ", ";background:", ";color:", ";font-family:", ";font-size:", ";box-sizing:border-box;margin-bottom:", ";border-top:3px solid ", ";padding:", ";", " ", ""], theme.orbit.borderRadiusLarge, getTypeToken(TOKENS.colorBorderAlert), getTypeToken(TOKENS.backgroundAlert), theme.orbit.paletteInkNormal, theme.orbit.fontFamily, theme.orbit.fontSizeTextNormal, getSpacingToken, getTypeToken(TOKENS.colorAccentBorder), closable ? rtlSpacing(`${theme.orbit.spaceSmall} ${theme.orbit.spaceLarge} ${theme.orbit.spaceSmall} ${theme.orbit.spaceSmall}`) : theme.orbit.spaceSmall, media.largeMobile(css(["border-top:1px solid ", ";border-", ":3px solid ", ";"], getTypeToken(TOKENS.colorBorderAlert), left, getTypeToken(TOKENS.colorAccentBorder))), media.tablet(css(["border-radius:", ";"], theme.orbit.borderRadiusNormal)))); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198
StyledAlert.defaultProps = {
theme: defaultTheme
};
const StyledIconContainer = styled(StyledDiv).withConfig({
displayName: "Alert__StyledIconContainer",
componentId: "sc-1fh23bc-2"
})(["", ""], ({
theme,
inlineActions
}) => css(["flex-shrink:0;margin:", ";color:", ";display:", ";align-items:", ";", ""], rtlSpacing(`0 ${theme.orbit.spaceXSmall} 0 0`), getTypeToken(TOKENS.colorIconAlert), inlineActions && "flex", inlineActions && "center", media.tablet(css(["margin:", ";", "{width:20px;height:20px;}"], rtlSpacing(`0 ${theme.orbit.spaceXSmall} 0 0`), StyledIcon)))); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198
StyledIconContainer.defaultProps = {
theme: defaultTheme
};
const StyledContentWrapper = styled(StyledDiv).withConfig({
displayName: "Alert__StyledContentWrapper",
componentId: "sc-1fh23bc-3"
})(["", ""], ({
title,
inlineActions
}) => css(["flex:1;display:flex;flex-direction:", ";align-items:", ";justify-content:", ";"], title && inlineActions ? "row" : "column", !title && "center", inlineActions && "space-between"));
const StyledTitle = styled(StyledDiv).withConfig({
displayName: "Alert__StyledTitle",
componentId: "sc-1fh23bc-4"
})(["", ""], ({
theme,
hasChildren,
inlineActions
}) => css(["color:", ";display:flex;align-items:center;min-height:20px;margin-bottom:", ";font-weight:", ";"], theme.orbit.paletteInkNormal, hasChildren && (inlineActions ? "0" : theme.orbit.spaceXXSmall), theme.orbit.fontWeightBold)); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198
StyledTitle.defaultProps = {
theme: defaultTheme
};
const StyledContent = styled(StyledDiv).withConfig({
displayName: "Alert__StyledContent",
componentId: "sc-1fh23bc-5"
})(["", ""], ({
inlineActions,
theme
}) => css(["display:flex;align-items:center;min-height:20px;width:", ";& a:not([class]),& ", "{", ";}& ", ",", ",", "{color:", ";}"], !inlineActions && "100%", StyledTextLink, getLinkStyle, Item, StyledText, StyledHeading, theme.orbit.paletteInkNormal)); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198
StyledContent.defaultProps = {
theme: defaultTheme
};
const CloseContainer = styled(StyledDiv).withConfig({
displayName: "Alert__CloseContainer",
componentId: "sc-1fh23bc-6"
})(["", ""], ({
theme,
hasChildren
}) => css(["position:absolute;top:", ";margin-top:", ";", ":0;margin-", ":", ";"], hasChildren ? 0 : "50%", !hasChildren && `-${theme.orbit.widthIconSmall}`, right, right, !hasChildren && theme.orbit.spaceXSmall)); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198
CloseContainer.defaultProps = {
theme: defaultTheme
};
const AlertCloseButton = ({
hasChildren,
dataTest,
onClick,
icon
}) => {
const translate = useTranslate();
return /*#__PURE__*/React.createElement(CloseContainer, {
hasChildren: hasChildren
}, /*#__PURE__*/React.createElement(ButtonLink, {
dataTest: dataTest,
onClick: onClick,
size: "small",
iconLeft: icon,
type: "secondary",
title: translate("button_close")
}));
};
const Alert = props => {
const {
type = TYPE_OPTIONS.INFO,
title,
icon,
closable,
onClose,
children,
dataTest,
spaceAfter,
suppressed,
inlineActions
} = props;
return /*#__PURE__*/React.createElement(StyledAlert, {
type: type,
icon: icon,
suppressed: suppressed,
closable: closable,
dataTest: dataTest,
spaceAfter: spaceAfter
}, icon && /*#__PURE__*/React.createElement(StyledIconContainer, {
type: type,
inlineActions: inlineActions
}, /*#__PURE__*/React.createElement(StyledIcon, {
type: type,
icon: icon
})), /*#__PURE__*/React.createElement(StyledContentWrapper, {
title: title,
inlineActions: inlineActions
}, title && /*#__PURE__*/React.createElement(StyledTitle, {
hasChildren: children,
inlineActions: inlineActions
}, title), children && !inlineActions && /*#__PURE__*/React.createElement(StyledContent, {
title: title,
type: type
}, children), inlineActions && /*#__PURE__*/React.createElement(StyledContent, {
title: title,
type: type,
inlineActions: inlineActions
}, inlineActions)), closable && /*#__PURE__*/React.createElement(AlertCloseButton, {
hasChildren: children,
dataTest: CLOSE_BUTTON_DATA_TEST,
onClick: onClose,
icon: /*#__PURE__*/React.createElement(Close, {
size: "small",
color: type
})
}));
};
export { default as AlertButton } from "./AlertButton";
export default Alert;