@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 (250 loc) • 8.72 kB
JavaScript
import * as React from "react";
import styled, { css } from "styled-components";
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 } from "../TextLink";
import { TYPE_OPTIONS, TOKENS, CLOSE_BUTTON_DATA_TEST } from "./consts";
import { rtlSpacing, right } 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
}) => {
const tokens = {
[TOKENS.colorIconAlert]: {
[TYPE_OPTIONS.INFO]: theme.orbit.paletteBlueDarker,
[TYPE_OPTIONS.SUCCESS]: theme.orbit.paletteGreenDarker,
[TYPE_OPTIONS.WARNING]: theme.orbit.paletteOrangeDarker,
[TYPE_OPTIONS.CRITICAL]: theme.orbit.paletteRedDarker
},
[TOKENS.backgroundAlert]: {
[TYPE_OPTIONS.INFO]: theme.orbit.backgroundAlertInfo,
[TYPE_OPTIONS.SUCCESS]: theme.orbit.backgroundAlertSuccess,
[TYPE_OPTIONS.WARNING]: theme.orbit.backgroundAlertWarning,
[TYPE_OPTIONS.CRITICAL]: theme.orbit.backgroundAlertCritical
},
[TOKENS.colorTextAlert]: {
[TYPE_OPTIONS.INFO]: theme.orbit.colorTextAlertInfo,
[TYPE_OPTIONS.SUCCESS]: theme.orbit.colorTextAlertSuccess,
[TYPE_OPTIONS.WARNING]: theme.orbit.colorTextAlertWarning,
[TYPE_OPTIONS.CRITICAL]: theme.orbit.colorTextAlertCritical
},
// 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
},
[TOKENS.colorBorderAlert]: {
[TYPE_OPTIONS.INFO]: theme.orbit.paletteBlueLightHover,
[TYPE_OPTIONS.SUCCESS]: theme.orbit.paletteGreenLightHover,
[TYPE_OPTIONS.WARNING]: theme.orbit.paletteOrangeLightHover,
[TYPE_OPTIONS.CRITICAL]: theme.orbit.paletteRedLightHover
}
};
return tokens[name][type];
};
const Icon = ({
icon,
type
}) => {
// Icon should be boolean and TRUE
if (typeof icon === "boolean" && icon) {
if (type === TYPE_OPTIONS.INFO) {
return React.createElement(InformationCircle, null);
}
if (type === TYPE_OPTIONS.SUCCESS) {
return React.createElement(Check, null);
}
if (type === TYPE_OPTIONS.WARNING) {
return React.createElement(AlertTriangle, null);
}
if (type === TYPE_OPTIONS.CRITICAL) {
return React.createElement(AlertCircle, null);
}
}
return icon;
};
const StyledDiv = ({
className,
children,
dataTest
}) => React.createElement("div", {
className: className,
"data-test": dataTest
}, children);
const StyledAlert = styled(StyledDiv).withConfig({
displayName: "Alert__StyledAlert",
componentId: "svgppc-0"
})(["position:relative;display:flex;width:100%;border-radius:", ";border:1px solid ", ";background:", ";color:", ";font-family:", ";font-size:", ";line-height:", ";box-sizing:border-box;margin-bottom:", ";padding:", ";", ""], ({
theme
}) => theme.orbit.borderRadiusNormal, getTypeToken(TOKENS.colorBorderAlert), getTypeToken(TOKENS.backgroundAlert), getTypeToken(TOKENS.colorTextAlert), ({
theme
}) => theme.orbit.fontFamily, ({
theme
}) => theme.orbit.fontSizeTextNormal, ({
theme
}) => theme.orbit.lineHeightTextNormal, getSpacingToken, ({
theme,
closable
}) => closable ? rtlSpacing(`${theme.orbit.spaceXSmall} ${theme.orbit.spaceXLarge} ${theme.orbit.spaceXSmall} ${theme.orbit.spaceXSmall}`) : theme.orbit.spaceXSmall, media.tablet(css(["padding:", ";"], ({
theme,
closable
}) => closable ? rtlSpacing(`${theme.orbit.paddingAlert} ${theme.orbit.spaceXXLarge} ${theme.orbit.paddingAlert} ${theme.orbit.paddingAlert}`) : theme.orbit.paddingAlert)));
StyledAlert.defaultProps = {
theme: defaultTheme
};
const IconContainer = styled(StyledDiv).withConfig({
displayName: "Alert__IconContainer",
componentId: "svgppc-1"
})(["flex-shrink:0;margin:", ";color:", ";display:", ";align-items:", ";", ""], ({
theme
}) => rtlSpacing(`0 ${theme.orbit.spaceXSmall} 0 0`), getTypeToken(TOKENS.colorIconAlert), ({
inlineActions
}) => inlineActions && "flex", ({
inlineActions
}) => inlineActions && "center", media.tablet(css(["margin:", ";"], ({
theme
}) => rtlSpacing(`0 ${theme.orbit.spaceSmall} 0 0`))));
IconContainer.defaultProps = {
theme: defaultTheme
};
const ContentWrapper = styled(StyledDiv).withConfig({
displayName: "Alert__ContentWrapper",
componentId: "svgppc-2"
})(["flex:1;display:flex;flex-direction:", ";align-items:", ";justify-content:", ";"], ({
title,
inlineActions
}) => title && (inlineActions ? "row" : "column"), ({
title
}) => !title && "center", ({
inlineActions
}) => inlineActions && "space-between");
const Title = styled(StyledDiv).withConfig({
displayName: "Alert__Title",
componentId: "svgppc-3"
})(["color:", ";display:flex;align-items:center;margin-bottom:", ";font-weight:", ";line-height:", ";min-height:", ";", ""], getTypeToken(TOKENS.colorIconAlert), ({
theme,
hasChildren,
inlineActions
}) => hasChildren && (inlineActions ? "0" : theme.orbit.spaceXXSmall), ({
theme
}) => theme.orbit.fontWeightBold, ({
theme
}) => theme.orbit.lineHeightHeading, ({
theme
}) => theme.orbit.heightIconMedium, media.tablet(css(["margin-bottom:", ";"], ({
theme,
hasChildren,
inlineActions
}) => hasChildren && (inlineActions ? "0" : theme.orbit.spaceXSmall))));
Title.defaultProps = {
theme: defaultTheme
};
const Content = styled(StyledDiv).withConfig({
displayName: "Alert__Content",
componentId: "svgppc-4"
})(["display:block;width:", ";& a,& ", "{color:", ";font-weight:", ";transition:color ", " ease-in-out;&:hover,&:focus,&:active{color:", ";}}& ", ",", ",", "{color:", ";}"], ({
inlineActions
}) => !inlineActions && "100%", StyledTextLink, getTypeToken(TOKENS.colorTextAlert), ({
theme
}) => theme.orbit.fontWeightMedium, ({
theme
}) => theme.orbit.durationFast, getTypeToken(TOKENS.colorTextLinkAlertHover), Item, StyledText, StyledHeading, getTypeToken(TOKENS.colorTextAlert));
Content.defaultProps = {
theme: defaultTheme
};
const CloseContainer = styled(StyledDiv).withConfig({
displayName: "Alert__CloseContainer",
componentId: "svgppc-5"
})(["position:absolute;top:", ";margin-top:", ";", ":0;margin-", ":", ";"], ({
hasChildren
}) => hasChildren ? 0 : "50%", ({
hasChildren,
theme
}) => !hasChildren && `-${theme.orbit.widthIconSmall}`, right, right, ({
hasChildren,
theme
}) => !hasChildren && theme.orbit.spaceXSmall);
CloseContainer.defaultProps = {
theme: defaultTheme
};
const AlertCloseButton = ({
hasChildren,
dataTest,
onClick,
icon
}) => {
const translate = useTranslate();
return React.createElement(CloseContainer, {
hasChildren: hasChildren
}, React.createElement(ButtonLink, {
dataTest: dataTest,
onClick: onClick,
size: "small",
icon: icon,
type: "secondary",
transparent: true,
title: translate("button_close")
}));
};
const Alert = props => {
const {
type = TYPE_OPTIONS.INFO,
title,
closable,
icon,
onClose = () => {},
children,
dataTest,
spaceAfter,
inlineActions = false
} = props;
return React.createElement(StyledAlert, {
type: type,
icon: icon,
closable: closable,
dataTest: dataTest,
spaceAfter: spaceAfter
}, icon && React.createElement(IconContainer, {
type: type,
inlineActions: inlineActions
}, React.createElement(Icon, {
type: type,
icon: icon
})), React.createElement(ContentWrapper, {
title: title,
inlineActions: inlineActions
}, title && React.createElement(Title, {
type: type,
hasChildren: children,
inlineActions: inlineActions
}, title), children && !inlineActions && React.createElement(Content, {
title: title,
type: type
}, children), inlineActions && React.createElement(Content, {
title: title,
type: type,
inlineActions: inlineActions
}, inlineActions)), closable && React.createElement(AlertCloseButton, {
hasChildren: children,
dataTest: CLOSE_BUTTON_DATA_TEST,
onClick: onClose,
icon: React.createElement(Close, {
size: "small",
color: type
})
}));
};
export default Alert;