vcc-ui
Version:
VCC UI is a collection of React UI Components that can be used for developing front-end applications at Volvo Car Corporation.
307 lines (278 loc) • 9.48 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; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import React from "react";
import PropTypes from "prop-types";
import { Click } from "../click";
import { Block, withTheme } from "../block";
import { Arrow } from "../arrow";
import { Icon } from "../icon";
import { Inline } from "../inline";
import { Spinner } from "../spinner";
import { BREAKPOINTS } from "../../constants/breakpoints";
import { COLORS } from "../../constants/colors";
import { deprecate } from "../../deprecate";
var styles = function styles(disabled, intent, variant, fullWidth) {
return _objectSpread({
display: "inline-block",
padding: "20px 50px",
textAlign: "center",
lineHeight: "1.2",
transition: "all 0.3s ease-out",
transitionProperty: "background, fill, stroke, color, border-color",
fontSize: "15px",
fontFamily: "Volvo Novum Regular, sans-serif",
position: "relative"
}, getButtonStyles(disabled, variant, intent), applyFullWidth(fullWidth));
};
var BREAKPOINT_MAPPING = {
s: BREAKPOINTS["onS"],
m: BREAKPOINTS["onM"],
l: BREAKPOINTS["onL"]
};
var applyFullWidth = function applyFullWidth(fullWidth) {
var fullWidthStyle = {
width: "100%",
display: "block"
};
if (typeof fullWidth === "boolean") {
return fullWidth ? fullWidthStyle : {};
}
var outputStyle = {};
fullWidth.forEach(function (breakpoint) {
outputStyle[BREAKPOINT_MAPPING[breakpoint]] = fullWidthStyle;
});
return outputStyle;
};
var getButtonStyles = function getButtonStyles(disabled, variant, intent) {
if (disabled) {
if (variant == "default") {
return {
cursor: "not-allowed",
background: "lightgrey",
color: "grey",
stroke: "grey",
fill: "grey",
":focus": {
outline: "2px solid #CCCCCC33"
}
};
}
if (variant == "outline") {
return {
cursor: "not-allowed",
border: "1px solid lightgrey",
color: "lightgrey",
stroke: "lightgrey",
fill: "lightgrey",
":focus": {
outline: "2px solid #CCCCCC33"
}
};
}
if (variant == "text") {
return {
cursor: "not-allowed",
fill: "lightgrey",
color: "lightgrey",
stroke: "lightgrey",
":focus": {
outline: "2px solid #CCCCCC33"
}
};
}
}
var activeBackground;
var color;
var defaultForeground;
var highlight;
if (intent == "primary") {
color = COLORS.primaryBlue;
defaultForeground = COLORS.white;
highlight = COLORS.primaryBlueLight;
activeBackground = "#0099ff";
}
if (intent == "primary-light") {
color = COLORS.white;
defaultForeground = COLORS.black;
activeBackground = "#eee";
}
if (intent == "secondary") {
color = COLORS.black;
defaultForeground = COLORS.white;
activeBackground = "#666";
}
if (intent == "destructive") {
color = COLORS.red;
defaultForeground = COLORS.white;
highlight = COLORS.redLight;
activeBackground = "#ff3f3f";
} // Variants
if (variant == "default") {
return {
border: "1px solid " + color,
background: color,
color: defaultForeground,
fill: defaultForeground,
stroke: defaultForeground,
":hover": {
background: highlight
},
":focus": {
outline: "2px solid ".concat(color, "33")
},
":focus:active": {
background: activeBackground
}
};
}
if (variant == "outline") {
return {
border: "1px solid " + color,
color: color,
fill: color,
stroke: color,
":hover": {
background: color,
color: defaultForeground,
borderColor: highlight,
fill: defaultForeground,
stroke: defaultForeground
},
":focus": {
outline: "2px solid ".concat(color, "33")
},
":focus:active": {
background: activeBackground
}
};
}
if (variant == "text") {
return {
fill: color,
color: color,
stroke: color,
":hover": {
color: highlight
},
":focus": {
outline: "2px solid ".concat(color, "33")
}
};
}
};
var arrows = {
up: {
":hover svg": {
transform: "translateY(-3px)"
}
},
down: {
":hover svg": {
transform: "translateY(3px)"
}
},
right: {
":hover svg": {
transform: "translateX(5px)"
}
},
left: {
":hover svg": {
transform: "translateX(-5px)"
}
}
};
var ButtonComponent = function ButtonComponent(_ref) {
var children = _ref.children,
intent = _ref.intent,
variant = _ref.variant,
loading = _ref.loading,
disabled = _ref.disabled,
arrow = _ref.arrow,
iconBefore = _ref.iconBefore,
iconAfter = _ref.iconAfter,
fullWidth = _ref.fullWidth,
theme = _ref.theme,
props = _objectWithoutProperties(_ref, ["children", "intent", "variant", "loading", "disabled", "arrow", "iconBefore", "iconAfter", "fullWidth", "theme"]);
deprecate("fullWidth property for <Button> compomnent is deprecated. Starting from version 1.x all buttons will be fullWidth be default. Please refer to the VCC UI 1.x Migration guide for more information", !(fullWidth.length === 1 && fullWidth[0] === "s"));
return React.createElement(Click, _extends({
disabled: disabled || loading
}, props, {
extend: _objectSpread({}, styles(disabled, intent, variant, fullWidth), arrow && !disabled && arrows[arrow], theme.button)
}), loading && React.createElement(Block, {
extend: {
position: "absolute",
marginLeft: "auto",
marginRight: "auto",
top: "14px",
left: 0,
right: 0
}
}, React.createElement(Spinner, {
color: "auto",
size: "30"
})), loading ? React.createElement(Inline, {
extend: {
visibility: "hidden"
}
}, children) : React.createElement(React.Fragment, null, iconBefore && React.createElement(Inline, {
extend: {
marginRight: "12px"
}
}, React.createElement(Icon, {
size: "s",
type: iconBefore
})), arrow && arrow === "left" && React.createElement(Inline, {
extend: {
marginRight: "8px"
}
}, React.createElement(Arrow, {
direction: "left"
})), children, arrow && arrow !== "left" && React.createElement(Inline, {
extend: {
marginLeft: "8px"
}
}, React.createElement(Arrow, {
direction: arrow
})), iconAfter && React.createElement(Inline, {
extend: {
marginLeft: "12px"
}
}, React.createElement(Icon, {
size: "s",
type: iconAfter
}))));
};
ButtonComponent.propTypes = {
/** A JSX node */
children: PropTypes.node,
intent: PropTypes.oneOf(["primary", "primary-light", "secondary", "destructive"]),
variant: PropTypes.oneOf(["default", "outline", "text"]),
loading: PropTypes.bool,
disabled: PropTypes.bool,
arrow: PropTypes.oneOf(["up", "down", "right", "left"]),
/** Add an icon before button text */
iconBefore: PropTypes.string,
/** Add an icon after button text */
iconAfter: PropTypes.string,
/**
* WARNING: DEPRECATED
* Allow the button to grow to the width of it's
* parent container on breakpoints `s`, `m` and `l` specified in an array,
* or use `false` or `true` instead of the array as a shortcut for all breakponts .
*/
fullWidth: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOf(["s", "m", "l"])), PropTypes.bool])
};
ButtonComponent.defaultProps = {
intent: "primary",
variant: "default",
loading: false,
disabled: false,
fullWidth: ["s"]
};
ButtonComponent.displayName = "Button";
var Button = withTheme(ButtonComponent);
export { Button };