@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.
463 lines (439 loc) • 21.8 kB
JavaScript
function _extends() { _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; }; return _extends.apply(this, arguments); }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } 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 = {
[]: {
[]: theme.orbit.heightButtonLarge,
[]: theme.orbit.heightButtonNormal,
[]: theme.orbit.heightButtonSmall
},
[]: {
[]: theme.orbit.widthIconMedium,
[]: theme.orbit.widthIconMedium,
[]: theme.orbit.widthIconSmall
},
[]: {
[]: theme.orbit.heightIconMedium,
[]: theme.orbit.heightIconMedium,
[]: theme.orbit.heightIconSmall
},
[]: {
[]: theme.orbit.fontSizeButtonLarge,
[]: theme.orbit.fontSizeButtonNormal,
[]: theme.orbit.fontSizeButtonSmall
},
[]: {
[]: theme.orbit.paddingButtonLarge,
[]: theme.orbit.paddingButtonNormal,
[]: theme.orbit.paddingButtonSmall
},
[]: {
[]: theme.orbit.paddingButtonLargeWithIcon,
[]: theme.orbit.paddingButtonNormalWithIcon,
[]: theme.orbit.paddingButtonSmallWithIcon
},
[]: {
[]: theme.orbit.marginButtonIconLarge,
[]: theme.orbit.marginButtonIconNormal,
[]: theme.orbit.marginButtonIconSmall
}
};
return tokens[name][size];
};
const getTypeToken = name => ({
theme,
type
}) => {
const tokens = {
[]: {
[]: theme.orbit.backgroundButtonPrimary,
[]: theme.orbit.backgroundButtonSecondary,
[]: theme.orbit.backgroundButtonInfo,
[]: theme.orbit.backgroundButtonSuccess,
[]: theme.orbit.backgroundButtonWarning,
[]: theme.orbit.backgroundButtonCritical,
[]: theme.orbit.backgroundButtonFacebook,
[]: theme.orbit.backgroundButtonGoogle,
[]: theme.orbit.paletteWhite // TODO: token backgroundButtonWhite
},
[]: {
[]: theme.orbit.backgroundButtonPrimaryHover,
[]: theme.orbit.backgroundButtonSecondaryHover,
[]: theme.orbit.backgroundButtonInfoHover,
[]: theme.orbit.backgroundButtonSuccessHover,
[]: theme.orbit.backgroundButtonWarningHover,
[]: theme.orbit.backgroundButtonCriticalHover,
[]: theme.orbit.backgroundButtonFacebookHover,
[]: theme.orbit.backgroundButtonGoogleHover,
[]: theme.orbit.paletteWhiteHover // TODO: token backgroundButtonWhiteHover
},
[]: {
[]: theme.orbit.backgroundButtonPrimaryActive,
[]: theme.orbit.backgroundButtonSecondaryActive,
[]: theme.orbit.backgroundButtonInfoActive,
[]: theme.orbit.backgroundButtonSuccessActive,
[]: theme.orbit.backgroundButtonWarningActive,
[]: theme.orbit.backgroundButtonCriticalActive,
[]: theme.orbit.backgroundButtonFacebookActive,
[]: theme.orbit.backgroundButtonGoogleActive,
[]: theme.orbit.paletteWhiteActive // TODO: token backgroundButtonWhiteActive
},
[]: {
[]: theme.orbit.backgroundButtonBordered,
[]: theme.orbit.backgroundButtonBordered,
[]: theme.orbit.backgroundButtonBordered,
[]: theme.orbit.backgroundButtonBordered,
[]: theme.orbit.backgroundButtonBordered,
[]: theme.orbit.backgroundButtonBordered,
[]: theme.orbit.backgroundButtonBordered,
[]: theme.orbit.backgroundButtonBordered,
[]: "transparent" // TODO: token backgroundButtonWhiteBordered
},
[]: {
[]: theme.orbit.backgroundButtonBorderedHover,
[]: theme.orbit.backgroundButtonBorderedHover,
[]: theme.orbit.backgroundButtonBorderedHover,
[]: theme.orbit.backgroundButtonBorderedHover,
[]: theme.orbit.backgroundButtonBorderedHover,
[]: theme.orbit.backgroundButtonBorderedHover,
[]: theme.orbit.backgroundButtonBorderedHover,
[]: theme.orbit.backgroundButtonBorderedHover,
[]: "rgba(255, 255, 255, 0.2)" // TODO: token backgroundButtonWhiteBorderedHover
},
[]: {
[]: theme.orbit.backgroundButtonBorderedActive,
[]: theme.orbit.backgroundButtonBorderedActive,
[]: theme.orbit.backgroundButtonBorderedActive,
[]: theme.orbit.backgroundButtonBorderedActive,
[]: theme.orbit.backgroundButtonBorderedActive,
[]: theme.orbit.backgroundButtonBorderedActive,
[]: theme.orbit.backgroundButtonBorderedActive,
[]: theme.orbit.backgroundButtonBorderedActive,
[]: "rgba(255, 255, 255, 0.25)" // TODO: token backgroundButtonWhiteBorderedActive
},
[]: {
[]: theme.orbit.colorTextButtonPrimary,
[]: theme.orbit.colorTextButtonSecondary,
[]: theme.orbit.colorTextButtonInfo,
[]: theme.orbit.colorTextButtonSuccess,
[]: theme.orbit.colorTextButtonWarning,
[]: theme.orbit.colorTextButtonCritical,
[]: theme.orbit.colorTextButtonFacebook,
[]: theme.orbit.colorTextButtonGoogle,
[]: theme.orbit.paletteInkNormal // TODO: token colorTextButtonWhite
},
[]: {
[]: theme.orbit.colorTextButtonPrimaryBordered,
[]: theme.orbit.colorTextButtonSecondaryBordered,
[]: theme.orbit.colorTextButtonInfoBordered,
[]: theme.orbit.colorTextButtonSuccessBordered,
[]: theme.orbit.colorTextButtonWarningBordered,
[]: theme.orbit.colorTextButtonCriticalBordered,
[]: theme.orbit.colorTextButtonFacebookBordered,
[]: theme.orbit.colorTextButtonGoogleBordered,
[]: theme.orbit.paletteWhite // TODO: token colorTextButtonWhiteBordered
},
[]: {
[]: theme.orbit.colorTextButtonPrimaryHover,
[]: theme.orbit.colorTextButtonSecondaryHover,
[]: theme.orbit.colorTextButtonInfoHover,
[]: theme.orbit.colorTextButtonSuccessHover,
[]: theme.orbit.colorTextButtonWarningHover,
[]: theme.orbit.colorTextButtonCriticalHover,
[]: theme.orbit.colorTextButtonFacebookHover,
[]: theme.orbit.colorTextButtonGoogleHover,
[]: theme.orbit.paletteInkNormalHover // TODO: token colorTextButtonWhiteHover
},
[]: {
[]: theme.orbit.colorTextButtonPrimaryBorderedHover,
[]: theme.orbit.colorTextButtonSecondaryBorderedHover,
[]: theme.orbit.colorTextButtonInfoBorderedHover,
[]: theme.orbit.colorTextButtonSuccessBorderedHover,
[]: theme.orbit.colorTextButtonWarningBorderedHover,
[]: theme.orbit.colorTextButtonCriticalBorderedHover,
[]: theme.orbit.colorTextButtonFacebookBorderedHover,
[]: theme.orbit.colorTextButtonGoogleBorderedHover,
[]: theme.orbit.paletteWhite // TODO: token colorTextButtonWhiteBorderedHover
},
[]: {
[]: theme.orbit.colorTextButtonPrimaryActive,
[]: theme.orbit.colorTextButtonSecondaryActive,
[]: theme.orbit.colorTextButtonInfoActive,
[]: theme.orbit.colorTextButtonSuccessActive,
[]: theme.orbit.colorTextButtonWarningActive,
[]: theme.orbit.colorTextButtonCriticalActive,
[]: theme.orbit.colorTextButtonFacebookActive,
[]: theme.orbit.colorTextButtonGoogleActive,
[]: theme.orbit.paletteInkNormalActive // TODO: token colorTextButtonWhiteActive
},
[]: {
[]: theme.orbit.colorTextButtonPrimaryBorderedActive,
[]: theme.orbit.colorTextButtonSecondaryBorderedActive,
[]: theme.orbit.colorTextButtonInfoBorderedActive,
[]: theme.orbit.colorTextButtonSuccessBorderedActive,
[]: theme.orbit.colorTextButtonWarningBorderedActive,
[]: theme.orbit.colorTextButtonCriticalBorderedActive,
[]: theme.orbit.colorTextButtonFacebookBorderedActive,
[]: theme.orbit.colorTextButtonGoogleBorderedActive,
[]: theme.orbit.paletteWhite // TODO: token colorTextButtonWhiteBorderedActive
},
[]: {
[]: theme.orbit.borderColorButtonPrimaryBordered,
[]: theme.orbit.borderColorButtonSecondaryBordered,
[]: theme.orbit.borderColorButtonInfoBordered,
[]: theme.orbit.borderColorButtonSuccessBordered,
[]: theme.orbit.borderColorButtonWarningBordered,
[]: theme.orbit.borderColorButtonCriticalBordered,
[]: theme.orbit.borderColorButtonFacebookBordered,
[]: theme.orbit.borderColorButtonGoogleBordered,
[]: theme.orbit.paletteWhite // TODO: token borderColorButtonWhiteBordered
},
[]: {
[]: theme.orbit.borderColorButtonPrimaryBorderedHover,
[]: theme.orbit.borderColorButtonSecondaryBorderedHover,
[]: theme.orbit.borderColorButtonInfoBorderedHover,
[]: theme.orbit.borderColorButtonSuccessBorderedHover,
[]: theme.orbit.borderColorButtonWarningBorderedHover,
[]: theme.orbit.borderColorButtonCriticalBorderedHover,
[]: theme.orbit.borderColorButtonFacebookBorderedHover,
[]: theme.orbit.borderColorButtonGoogleBorderedHover,
[]: theme.orbit.paletteWhite // TODO: token borderColorButtonWhiteBorderedHover
},
[]: {
[]: theme.orbit.borderColorButtonPrimaryBorderedActive,
[]: theme.orbit.borderColorButtonSecondaryBorderedActive,
[]: theme.orbit.borderColorButtonInfoBorderedActive,
[]: theme.orbit.borderColorButtonSuccessBorderedActive,
[]: theme.orbit.borderColorButtonWarningBorderedActive,
[]: theme.orbit.borderColorButtonCriticalBorderedActive,
[]: theme.orbit.borderColorButtonFacebookBorderedActive,
[]: theme.orbit.borderColorButtonGoogleBorderedActive,
[]: theme.orbit.paletteWhite // TODO: token borderColorButtonWhiteBorderedActive
}
};
return tokens[name][type];
};
const IconContainer = styled(({
className,
children
}) => React.createElement("div", {
className: className
}, children)).withConfig({
displayName: "Button__IconContainer",
componentId: "sc-1brqp3f-0"
})(["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, ({
sizeIcon
}) => getSize(sizeIcon), ({
sizeIcon
}) => getSize(sizeIcon));
IconContainer.defaultProps = {
theme: defaultTokens
};
const IconContainerRight = styled(IconContainer).withConfig({
displayName: "Button__IconContainerRight",
componentId: "sc-1brqp3f-1"
})(["margin-right:0;margin-left:", ";"], ({
onlyIcon
}) => onlyIcon ? "0" : getSizeToken(TOKENS.marginRightIcon));
IconContainerRight.defaultProps = {
theme: defaultTokens
};
export 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",
componentId: "sc-1brqp3f-2"
})(["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
}) => bordered ? getTypeToken(TOKENS.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
}) => !disabled && (bordered ? getTypeToken(TOKENS.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
}) => !disabled && (bordered ? getTypeToken(TOKENS.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));
StyledButton.defaultProps = {
theme: defaultTokens
};
const StyledButtonContent = styled.div.withConfig({
displayName: "Button__StyledButtonContent",
componentId: "sc-1brqp3f-3"
})(["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;