UNPKG

@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.

246 lines (235 loc) 8.07 kB
import * as React from "react"; import styled 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 { DictionaryContext } from "../Dictionary"; import { pureTranslate } from "../Translate"; const getTypeToken = name => ({ theme, type }) => { const tokens = { [TOKENS.colorIconAlert]: { [TYPE_OPTIONS.INFO]: theme.orbit.colorAlertIconInfo, [TYPE_OPTIONS.SUCCESS]: theme.orbit.colorAlertIconSuccess, [TYPE_OPTIONS.WARNING]: theme.orbit.colorAlertIconWarning, [TYPE_OPTIONS.CRITICAL]: theme.orbit.colorAlertIconCritical }, [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 } }; 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%;padding:", ";border-radius:", ";background:", ";color:", ";font-family:", ";font-size:", ";box-sizing:border-box;margin-bottom:", ";"], ({ theme, icon, closable }) => rtlSpacing(closable ? icon && `${theme.orbit.paddingAlert} ${theme.orbit.spaceXXLarge} ${theme.orbit.paddingAlert} ${theme.orbit.paddingAlert}` || `${theme.orbit.paddingAlert} ${theme.orbit.spaceXXLarge} ${theme.orbit.paddingAlert} ${theme.orbit.paddingAlert}` : icon && `${theme.orbit.paddingAlert} ${theme.orbit.paddingAlert} ${theme.orbit.paddingAlert} ${theme.orbit.paddingAlert}` || `${theme.orbit.paddingAlert}`), ({ theme }) => theme.orbit.borderRadiusNormal, getTypeToken(TOKENS.backgroundAlert), getTypeToken(TOKENS.colorTextAlert), ({ theme }) => theme.orbit.fontFamily, ({ theme }) => theme.orbit.fontSizeTextNormal, getSpacingToken); 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.spaceSmall} 0 0`), getTypeToken(TOKENS.colorIconAlert), ({ inlineActions }) => inlineActions && "flex", ({ inlineActions }) => inlineActions && "center"); 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" })(["display:flex;align-items:center;margin-bottom:", ";font-weight:", ";line-height:", ";min-height:", ";"], ({ theme, hasChildren, inlineActions }) => hasChildren && (inlineActions ? "0" : theme.orbit.spaceXSmall), ({ theme }) => theme.orbit.fontWeightBold, ({ theme }) => theme.orbit.lineHeightHeading, ({ theme }) => theme.orbit.heightIconMedium); Title.defaultProps = { theme: defaultTheme }; const Content = styled(StyledDiv).withConfig({ displayName: "Alert__Content", componentId: "svgppc-4" })(["display:block;margin-bottom:", ";line-height:", ";& a,& ", "{color:", ";font-weight:", ";transition:color ", " ease-in-out;&:hover,&:focus,&:active{color:", ";}}& ", ",", "{color:", ";}"], ({ theme, title, inlineActions }) => title && (inlineActions ? "0" : theme.orbit.spaceXXSmall), ({ theme }) => theme.orbit.lineHeightText, StyledTextLink, getTypeToken(TOKENS.colorTextAlert), ({ theme }) => theme.orbit.fontWeightMedium, ({ theme }) => theme.orbit.durationFast, getTypeToken(TOKENS.colorTextLinkAlertHover), Item, StyledText, 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 dictionary = React.useContext(DictionaryContext); return React.createElement(CloseContainer, { hasChildren: hasChildren }, React.createElement(ButtonLink, { dataTest: dataTest, onClick: onClick, size: "small", icon: icon, transparent: true, title: pureTranslate(dictionary, "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, { 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;