UNPKG

@kiwicom/orbit-components

Version:

<div align="center"> <a href="https://orbit.kiwi" target="_blank"> <img alt="orbit-components" src="https://orbit.kiwi/wp-content/uploads/2018/08/orbit-components.png" srcset="https://orbit.kiwi/wp-content/uploads/2018/08/orbit-components@2x.png 2x"

317 lines (301 loc) 17.6 kB
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } import * as React from "react"; import styled from "styled-components"; import defaultTokens from "../defaultTokens"; import { ICON_SIZES } from "../Icon/consts"; import { TYPE_OPTIONS, SIZE_OPTIONS, TOKENS } from "./consts"; import Loading, { StyledSpinner } from "../Loading"; import { getSize } from "../Icon"; const getSizeToken = name => ({ theme, size }) => { const tokens = { [TOKENS.heightButton]: { [SIZE_OPTIONS.LARGE]: theme.orbit.heightButtonLarge, [SIZE_OPTIONS.NORMAL]: theme.orbit.heightButtonNormal, [SIZE_OPTIONS.SMALL]: theme.orbit.heightButtonSmall }, [TOKENS.loadingWidth]: { [SIZE_OPTIONS.LARGE]: theme.orbit.widthIconMedium, [SIZE_OPTIONS.NORMAL]: theme.orbit.widthIconMedium, [SIZE_OPTIONS.SMALL]: theme.orbit.widthIconSmall }, [TOKENS.loadingHeight]: { [SIZE_OPTIONS.LARGE]: theme.orbit.heightIconMedium, [SIZE_OPTIONS.NORMAL]: theme.orbit.heightIconMedium, [SIZE_OPTIONS.SMALL]: theme.orbit.heightIconSmall }, [TOKENS.fontSizeButton]: { [SIZE_OPTIONS.LARGE]: theme.orbit.fontSizeButtonLarge, [SIZE_OPTIONS.NORMAL]: theme.orbit.fontSizeButtonNormal, [SIZE_OPTIONS.SMALL]: theme.orbit.fontSizeButtonSmall }, [TOKENS.paddingButton]: { [SIZE_OPTIONS.LARGE]: theme.orbit.paddingButtonLarge, [SIZE_OPTIONS.NORMAL]: theme.orbit.paddingButtonNormal, [SIZE_OPTIONS.SMALL]: theme.orbit.paddingButtonSmall }, [TOKENS.paddingButtonWithIcon]: { [SIZE_OPTIONS.LARGE]: theme.orbit.paddingButtonLargeWithIcon, [SIZE_OPTIONS.NORMAL]: theme.orbit.paddingButtonNormalWithIcon, [SIZE_OPTIONS.SMALL]: theme.orbit.paddingButtonSmallWithIcon }, [TOKENS.marginRightIcon]: { [SIZE_OPTIONS.LARGE]: theme.orbit.marginButtonIconLarge, [SIZE_OPTIONS.NORMAL]: theme.orbit.marginButtonIconNormal, [SIZE_OPTIONS.SMALL]: theme.orbit.marginButtonIconSmall } }; return tokens[name][size]; }; const getTypeToken = name => ({ theme, type }) => { const tokens = { [TOKENS.backgroundButton]: { [TYPE_OPTIONS.PRIMARY]: theme.orbit.backgroundButtonPrimary, [TYPE_OPTIONS.SECONDARY]: theme.orbit.backgroundButtonSecondary, [TYPE_OPTIONS.INFO]: theme.orbit.backgroundButtonInfo, [TYPE_OPTIONS.SUCCESS]: theme.orbit.backgroundButtonSuccess, [TYPE_OPTIONS.WARNING]: theme.orbit.backgroundButtonWarning, [TYPE_OPTIONS.CRITICAL]: theme.orbit.backgroundButtonCritical, [TYPE_OPTIONS.FACEBOOK]: theme.orbit.backgroundButtonFacebook, [TYPE_OPTIONS.GOOGLE]: theme.orbit.backgroundButtonGoogle }, [TOKENS.backgroundButtonHover]: { [TYPE_OPTIONS.PRIMARY]: theme.orbit.backgroundButtonPrimaryHover, [TYPE_OPTIONS.SECONDARY]: theme.orbit.backgroundButtonSecondaryHover, [TYPE_OPTIONS.INFO]: theme.orbit.backgroundButtonInfoHover, [TYPE_OPTIONS.SUCCESS]: theme.orbit.backgroundButtonSuccessHover, [TYPE_OPTIONS.WARNING]: theme.orbit.backgroundButtonWarningHover, [TYPE_OPTIONS.CRITICAL]: theme.orbit.backgroundButtonCriticalHover, [TYPE_OPTIONS.FACEBOOK]: theme.orbit.backgroundButtonFacebookHover, [TYPE_OPTIONS.GOOGLE]: theme.orbit.backgroundButtonGoogleHover }, [TOKENS.backgroundButtonActive]: { [TYPE_OPTIONS.PRIMARY]: theme.orbit.backgroundButtonPrimaryActive, [TYPE_OPTIONS.SECONDARY]: theme.orbit.backgroundButtonSecondaryActive, [TYPE_OPTIONS.INFO]: theme.orbit.backgroundButtonInfoActive, [TYPE_OPTIONS.SUCCESS]: theme.orbit.backgroundButtonSuccessActive, [TYPE_OPTIONS.WARNING]: theme.orbit.backgroundButtonWarningActive, [TYPE_OPTIONS.CRITICAL]: theme.orbit.backgroundButtonCriticalActive, [TYPE_OPTIONS.FACEBOOK]: theme.orbit.backgroundButtonFacebookActive, [TYPE_OPTIONS.GOOGLE]: theme.orbit.backgroundButtonGoogleActive }, [TOKENS.colorTextButton]: { [TYPE_OPTIONS.PRIMARY]: theme.orbit.colorTextButtonPrimary, [TYPE_OPTIONS.SECONDARY]: theme.orbit.colorTextButtonSecondary, [TYPE_OPTIONS.INFO]: theme.orbit.colorTextButtonInfo, [TYPE_OPTIONS.SUCCESS]: theme.orbit.colorTextButtonSuccess, [TYPE_OPTIONS.WARNING]: theme.orbit.colorTextButtonWarning, [TYPE_OPTIONS.CRITICAL]: theme.orbit.colorTextButtonCritical, [TYPE_OPTIONS.FACEBOOK]: theme.orbit.colorTextButtonFacebook, [TYPE_OPTIONS.GOOGLE]: theme.orbit.colorTextButtonGoogle }, [TOKENS.colorTextButtonBordered]: { [TYPE_OPTIONS.PRIMARY]: theme.orbit.colorTextButtonPrimaryBordered, [TYPE_OPTIONS.SECONDARY]: theme.orbit.colorTextButtonSecondaryBordered, [TYPE_OPTIONS.INFO]: theme.orbit.colorTextButtonInfoBordered, [TYPE_OPTIONS.SUCCESS]: theme.orbit.colorTextButtonSuccessBordered, [TYPE_OPTIONS.WARNING]: theme.orbit.colorTextButtonWarningBordered, [TYPE_OPTIONS.CRITICAL]: theme.orbit.colorTextButtonCriticalBordered, [TYPE_OPTIONS.FACEBOOK]: theme.orbit.colorTextButtonFacebookBordered, [TYPE_OPTIONS.GOOGLE]: theme.orbit.colorTextButtonGoogleBordered }, [TOKENS.colorTextButtonHover]: { [TYPE_OPTIONS.PRIMARY]: theme.orbit.colorTextButtonPrimaryHover, [TYPE_OPTIONS.SECONDARY]: theme.orbit.colorTextButtonSecondaryHover, [TYPE_OPTIONS.INFO]: theme.orbit.colorTextButtonInfoHover, [TYPE_OPTIONS.SUCCESS]: theme.orbit.colorTextButtonSuccessHover, [TYPE_OPTIONS.WARNING]: theme.orbit.colorTextButtonWarningHover, [TYPE_OPTIONS.CRITICAL]: theme.orbit.colorTextButtonCriticalHover, [TYPE_OPTIONS.FACEBOOK]: theme.orbit.colorTextButtonFacebookHover, [TYPE_OPTIONS.GOOGLE]: theme.orbit.colorTextButtonGoogleHover }, [TOKENS.colorTextButtonBorderedHover]: { [TYPE_OPTIONS.PRIMARY]: theme.orbit.colorTextButtonPrimaryBorderedHover, [TYPE_OPTIONS.SECONDARY]: theme.orbit.colorTextButtonSecondaryBorderedHover, [TYPE_OPTIONS.INFO]: theme.orbit.colorTextButtonInfoBorderedHover, [TYPE_OPTIONS.SUCCESS]: theme.orbit.colorTextButtonSuccessBorderedHover, [TYPE_OPTIONS.WARNING]: theme.orbit.colorTextButtonWarningBorderedHover, [TYPE_OPTIONS.CRITICAL]: theme.orbit.colorTextButtonCriticalBorderedHover, [TYPE_OPTIONS.FACEBOOK]: theme.orbit.colorTextButtonFacebookBorderedHover, [TYPE_OPTIONS.GOOGLE]: theme.orbit.colorTextButtonGoogleBorderedHover }, [TOKENS.colorTextButtonActive]: { [TYPE_OPTIONS.PRIMARY]: theme.orbit.colorTextButtonPrimaryActive, [TYPE_OPTIONS.SECONDARY]: theme.orbit.colorTextButtonSecondaryActive, [TYPE_OPTIONS.INFO]: theme.orbit.colorTextButtonInfoActive, [TYPE_OPTIONS.SUCCESS]: theme.orbit.colorTextButtonSuccessActive, [TYPE_OPTIONS.WARNING]: theme.orbit.colorTextButtonWarningActive, [TYPE_OPTIONS.CRITICAL]: theme.orbit.colorTextButtonCriticalActive, [TYPE_OPTIONS.FACEBOOK]: theme.orbit.colorTextButtonFacebookActive, [TYPE_OPTIONS.GOOGLE]: theme.orbit.colorTextButtonGoogleActive }, [TOKENS.colorTextButtonBorderedActive]: { [TYPE_OPTIONS.PRIMARY]: theme.orbit.colorTextButtonPrimaryBorderedActive, [TYPE_OPTIONS.SECONDARY]: theme.orbit.colorTextButtonSecondaryBorderedActive, [TYPE_OPTIONS.INFO]: theme.orbit.colorTextButtonInfoBorderedActive, [TYPE_OPTIONS.SUCCESS]: theme.orbit.colorTextButtonSuccessBorderedActive, [TYPE_OPTIONS.WARNING]: theme.orbit.colorTextButtonWarningBorderedActive, [TYPE_OPTIONS.CRITICAL]: theme.orbit.colorTextButtonCriticalBorderedActive, [TYPE_OPTIONS.FACEBOOK]: theme.orbit.colorTextButtonFacebookBorderedActive, [TYPE_OPTIONS.GOOGLE]: theme.orbit.colorTextButtonGoogleBorderedActive }, [TOKENS.borderColorButton]: { [TYPE_OPTIONS.PRIMARY]: theme.orbit.borderColorButtonPrimaryBordered, [TYPE_OPTIONS.SECONDARY]: theme.orbit.borderColorButtonSecondaryBordered, [TYPE_OPTIONS.INFO]: theme.orbit.borderColorButtonInfoBordered, [TYPE_OPTIONS.SUCCESS]: theme.orbit.borderColorButtonSuccessBordered, [TYPE_OPTIONS.WARNING]: theme.orbit.borderColorButtonWarningBordered, [TYPE_OPTIONS.CRITICAL]: theme.orbit.borderColorButtonCriticalBordered, [TYPE_OPTIONS.FACEBOOK]: theme.orbit.borderColorButtonFacebookBordered, [TYPE_OPTIONS.GOOGLE]: theme.orbit.borderColorButtonGoogleBordered }, [TOKENS.borderColorButtonHover]: { [TYPE_OPTIONS.PRIMARY]: theme.orbit.borderColorButtonPrimaryBorderedHover, [TYPE_OPTIONS.SECONDARY]: theme.orbit.borderColorButtonSecondaryBorderedHover, [TYPE_OPTIONS.INFO]: theme.orbit.borderColorButtonInfoBorderedHover, [TYPE_OPTIONS.SUCCESS]: theme.orbit.borderColorButtonSuccessBorderedHover, [TYPE_OPTIONS.WARNING]: theme.orbit.borderColorButtonWarningBorderedHover, [TYPE_OPTIONS.CRITICAL]: theme.orbit.borderColorButtonCriticalBorderedHover, [TYPE_OPTIONS.FACEBOOK]: theme.orbit.borderColorButtonFacebookBorderedHover, [TYPE_OPTIONS.GOOGLE]: theme.orbit.borderColorButtonGoogleBorderedHover }, [TOKENS.borderColorButtonActive]: { [TYPE_OPTIONS.PRIMARY]: theme.orbit.borderColorButtonPrimaryBorderedActive, [TYPE_OPTIONS.SECONDARY]: theme.orbit.borderColorButtonSecondaryBorderedActive, [TYPE_OPTIONS.INFO]: theme.orbit.borderColorButtonInfoBorderedActive, [TYPE_OPTIONS.SUCCESS]: theme.orbit.borderColorButtonSuccessBorderedActive, [TYPE_OPTIONS.WARNING]: theme.orbit.borderColorButtonWarningBorderedActive, [TYPE_OPTIONS.CRITICAL]: theme.orbit.borderColorButtonCriticalBorderedActive, [TYPE_OPTIONS.FACEBOOK]: theme.orbit.borderColorButtonFacebookBorderedActive, [TYPE_OPTIONS.GOOGLE]: theme.orbit.borderColorButtonGoogleBorderedActive } }; return tokens[name][type]; }; const IconContainer = styled(({ className, children }) => React.createElement( "div", { className: className }, children )).withConfig({ displayName: "Button__IconContainer" })(["display:flex;flex-direction:row;align-items:center;justify-content:center;margin-right:", ";color:", ";transition:background ", " ease-in-out,box-shadow ", " ease-in-out;> *{width:", ";height:", ";}"], ({ onlyIcon }) => onlyIcon ? "0" : getSizeToken(TOKENS.marginRightIcon), ({ bordered }) => bordered ? getTypeToken(TOKENS.colorTextButtonBordered) : getTypeToken(TOKENS.colorTextButton), ({ theme }) => theme.orbit.durationFast, ({ theme }) => theme.orbit.durationFast, getSize(), getSize()); IconContainer.defaultProps = { theme: defaultTokens }; const IconContainerRight = styled(IconContainer).withConfig({ displayName: "Button__IconContainerRight" })(["margin-right:0;margin-left:", ";"], ({ onlyIcon }) => onlyIcon ? "0" : getSizeToken(TOKENS.marginRightIcon)); IconContainerRight.defaultProps = { theme: defaultTokens }; const StyledButton = styled((_ref) => { let { theme, component, circled, external, type, icon, iconLeft, iconRight, sizeIcon, width, bordered, loading, onlyIcon, block, style, dataTest, submit } = _ref, props = _objectWithoutProperties(_ref, ["theme", "component", "circled", "external", "type", "icon", "iconLeft", "iconRight", "sizeIcon", "width", "bordered", "loading", "onlyIcon", "block", "style", "dataTest", "submit"]); const isButtonWithHref = component === "button" && props.href; const Component = isButtonWithHref ? "a" : component; const buttonType = submit ? "submit" : "button"; return React.createElement( Component, _extends({ "data-test": dataTest, type: !isButtonWithHref ? buttonType : undefined }, props), props.children ); }).withConfig({ displayName: "Button__StyledButton" })(["position:relative;display:", ";justify-content:center;align-items:center;box-sizing:border-box;appearance:none;text-decoration:none;width:", ";flex:", ";height:", ";background:", ";color:", " !important;border:0;border-radius:", ";padding:0;padding-right:", ";padding-left:", ";font-weight:", "!important;font-size:", ";cursor:", ";transition:all 0.15s ease-in-out !important;outline:0;opacity:", ";pointer-events:", ";box-shadow:", ";&:hover{background:", ";box-shadow:", ";color:", "!important;", "{color:", ";}}&:active{", ";background:", ";box-shadow:", ";color:", "!important;& ", "{color:", ";}}&:enabled:focus{box-shadow:", " ", ";}", "{width:", ";height:", ";}"], ({ href, component }) => href || component === "a" ? "inline-flex" : "flex", ({ block, width, onlyIcon }) => block ? "100%" : width && `${width}px` || onlyIcon && getSizeToken(TOKENS.heightButton) || "auto", ({ block }) => block ? "1 1 100%" : "0 0 auto", getSizeToken(TOKENS.heightButton), ({ bordered, theme }) => bordered ? theme.orbit.backgroundButtonBordered : getTypeToken(TOKENS.backgroundButton), ({ bordered }) => bordered ? getTypeToken(TOKENS.colorTextButtonBordered) : getTypeToken(TOKENS.colorTextButton), ({ theme, circled }) => circled ? getSizeToken(TOKENS.heightButton) : theme.orbit.borderRadiusNormal, ({ onlyIcon, iconRight }) => onlyIcon && "0" || (iconRight ? getSizeToken(TOKENS.paddingButtonWithIcon) : getSizeToken(TOKENS.paddingButton)), ({ onlyIcon, icon, iconLeft }) => onlyIcon && "0" || (iconLeft || icon ? getSizeToken(TOKENS.paddingButtonWithIcon) : getSizeToken(TOKENS.paddingButton)), ({ theme }) => theme.orbit.fontWeightBold, getSizeToken(TOKENS.fontSizeButton), ({ disabled }) => disabled ? "default" : "pointer", ({ disabled, theme }) => disabled && theme.orbit.opacityButtonDisabled, ({ disabled }) => disabled && "none", ({ bordered, theme, type }) => bordered && `inset 0 0 0 1px ${getTypeToken(TOKENS.borderColorButton)({ theme, type })}`, ({ disabled, bordered, theme }) => !disabled && (bordered ? theme.orbit.backgroundButtonBorderedHover : getTypeToken(TOKENS.backgroundButtonHover)), ({ disabled, bordered, theme, type }) => !disabled && bordered && `inset 0 0 0 1px ${getTypeToken(TOKENS.borderColorButtonHover)({ theme, type })}`, ({ disabled, bordered }) => !disabled && (bordered ? getTypeToken(TOKENS.colorTextButtonBorderedHover) : getTypeToken(TOKENS.colorTextButtonHover)), IconContainer, ({ disabled, bordered }) => !disabled && (bordered ? getTypeToken(TOKENS.colorTextButtonBorderedHover) : getTypeToken(TOKENS.colorTextButtonHover)), ({ disabled, theme }) => !disabled && `transform: scale(${theme.orbit.modifierScaleButtonActive})`, ({ disabled, bordered, theme }) => !disabled && (bordered ? theme.orbit.backgroundButtonBorderedActive : getTypeToken(TOKENS.backgroundButtonActive)), ({ disabled, bordered, theme, type }) => !disabled && bordered && `inset 0 0 0 1px ${getTypeToken(TOKENS.borderColorButtonActive)({ theme, type })}`, ({ disabled, bordered }) => !disabled && (bordered ? getTypeToken(TOKENS.colorTextButtonBorderedActive) : getTypeToken(TOKENS.colorTextButtonActive)), IconContainer, ({ disabled, bordered }) => !disabled && (bordered ? getTypeToken(TOKENS.colorTextButtonBorderedActive) : getTypeToken(TOKENS.colorTextButtonActive)), ({ bordered, theme, type }) => bordered && `inset 0 0 0 1px ${getTypeToken(TOKENS.borderColorButton)({ theme, type })},`, ({ theme }) => theme.orbit.boxShadowButtonFocus, StyledSpinner, getSizeToken(TOKENS.loadingWidth), getSizeToken(TOKENS.loadingHeight)); export { StyledButton }; StyledButton.defaultProps = { theme: defaultTokens }; const StyledButtonContent = styled.div.withConfig({ displayName: "Button__StyledButtonContent" })(["visibility:", ";height:100%;display:flex;justify-content:center;align-items:center;"], ({ loading }) => loading && "hidden"); StyledButtonContent.defaultProps = { theme: defaultTokens }; const Button = props => { const { component = "button", children, bordered, disabled, href, size = SIZE_OPTIONS.NORMAL, icon, iconRight, external, type = TYPE_OPTIONS.PRIMARY, block, loading = false, width = 0 } = props; const iconLeft = props.iconLeft || icon; const sizeIcon = size === ICON_SIZES.SMALL ? ICON_SIZES.SMALL : ICON_SIZES.MEDIUM; const onlyIcon = iconLeft && !children; const isDisabled = loading || disabled; return React.createElement( StyledButton, _extends({ bordered: bordered, block: block, component: component, disabled: isDisabled, loading: loading, onlyIcon: onlyIcon, size: size, sizeIcon: sizeIcon, target: href && external ? "_blank" : undefined, type: type, width: width }, props), loading && React.createElement(Loading, { type: "buttonLoader" }), React.createElement( StyledButtonContent, { loading: loading }, iconLeft && React.createElement( IconContainer, { bordered: bordered, onlyIcon: onlyIcon, size: size, sizeIcon: sizeIcon, type: type }, iconLeft ), children, iconRight && React.createElement( IconContainerRight, { bordered: bordered, onlyIcon: onlyIcon, size: size, sizeIcon: sizeIcon, type: type }, iconRight ) ) ); }; export default Button;