UNPKG

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.

354 lines (321 loc) 12.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Button = void 0; var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _reactFela = require("react-fela"); var _click = require("../click"); var _block = require("../block"); var _arrow = require("../arrow"); var _icon = require("../icon"); var _inline = require("../inline"); var _spinner = require("../spinner"); var _getThemeStyle = require("../../get-theme-style"); var _sizeToRem = require("../../size-to-rem"); var _deprecate = require("../../deprecate"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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 ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(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; } var padding = function padding(x, y) { return { padding: "".concat(x, "px ").concat(y, "px") }; }; var intentStyleMap = function intentStyleMap(_ref) { var tokens = _ref.tokens; return { primary: { color: tokens.buttonPrimaryColor, defaultForeground: tokens.buttonPrimaryForeground, highlight: tokens.buttonPrimaryHoverBackground, activeBackground: tokens.buttonPrimaryActiveBackground }, // deprecated, remove primary light in in 2.x 'primary-light': { color: tokens.buttonPrimaryLightColor, defaultForeground: tokens.buttonPrimaryLightForeground, activeBackground: tokens.buttonPrimaryLightActiveBackground }, secondary: { color: tokens.buttonSecondaryColor, defaultForeground: tokens.buttonSecondaryForeground, activeBackground: tokens.buttonSecondaryActiveBackground }, destructive: { color: tokens.buttonDestructiveColor, defaultForeground: tokens.buttonDestructiveForeground, highlight: tokens.buttonDestructiveHoverBackground, activeBackground: tokens.buttonDestructiveActiveBackground } }; }; var arrowTransform = { up: 'translateY(-3px)', down: 'translateY(3px)', right: 'translateX(5px)', left: 'translateX(-5px)' }; var button = function button(_ref2) { var disabled = _ref2.disabled, intent = _ref2.intent, variant = _ref2.variant, size = _ref2.size, loading = _ref2.loading, arrow = _ref2.arrow, theme = _ref2.theme; var _intentStyleMap$inten = intentStyleMap(theme)[intent], color = _intentStyleMap$inten.color, defaultForeground = _intentStyleMap$inten.defaultForeground, activeBackground = _intentStyleMap$inten.activeBackground, highlight = _intentStyleMap$inten.highlight; return _objectSpread({ display: 'inline-flex', flexShrink: 0, justifyContent: 'center', alignItems: 'baseline' }, padding(theme.tokens.buttonPaddingVertical, theme.tokens.buttonPaddingHorizontal), { textAlign: 'center', fontSize: (0, _sizeToRem.sizeToRem)(2), lineHeight: 1.2, transitionDuration: disabled ? 0 : '300ms', transitionTimingFunction: 'ease-out', transitionProperty: 'background, fill, stroke, color, border-color', borderColor: 'transparent', borderStyle: 'solid', borderWidth: 1, fontWeight: 400, ':focus': { outline: "2px solid ".concat(color, "33"), ':active': { background: activeBackground } }, extend: [{ condition: size === 'small', style: _objectSpread({ fontSize: (0, _sizeToRem.sizeToRem)(1.5) }, padding(theme.tokens.buttonPaddingVertical - theme.baselineGrid, theme.tokens.buttonPaddingHorizontal - theme.baselineGrid * 3), { '> div svg': { height: theme.baselineGrid * 3, width: theme.baselineGrid * 3 } }) }, { condition: size === 'large', style: _objectSpread({ fontSize: (0, _sizeToRem.sizeToRem)(3) }, padding(theme.tokens.buttonPaddingVertical + theme.baselineGrid, theme.tokens.buttonPaddingHorizontal + theme.baselineGrid * 2), { '> div svg': { height: theme.baselineGrid * 5, width: theme.baselineGrid * 5 } }) }, { condition: loading, style: { justifyContent: 'center', alignItems: 'center' } }, { condition: !disabled, style: { extend: [{ condition: variant === 'default', style: { borderColor: color, background: color, color: defaultForeground, fill: defaultForeground, stroke: defaultForeground, ':hover': { borderColor: highlight, background: highlight } } }, { condition: variant === 'outline', style: { borderColor: color, color: color, fill: color, stroke: color, ':hover': { background: color, color: defaultForeground, borderColor: highlight, fill: defaultForeground, stroke: defaultForeground } } }, { condition: variant === 'text', style: { borderColor: 'transparent', fill: color, color: color, stroke: color, ':hover': { color: highlight } } }, { condition: arrow, style: { ':hover svg': { transform: arrowTransform[arrow] } } }] } }, { condition: loading, style: { pointerEvents: 'none' } }, { condition: disabled, style: { cursor: 'not-allowed', fill: theme.color.foreground.secondary, color: theme.color.foreground.secondary, stroke: theme.color.foreground.secondary, ':focus': { outline: '2px solid #CCCCCC33' }, extend: [{ condition: variant === 'default', style: { borderColor: 'lightgrey', background: 'lightgrey', color: 'grey', stroke: 'grey', fill: 'grey' } }, { condition: variant === 'outline', style: { borderColor: 'lightgrey' } }] } }] }); }; var Button = _react.default.forwardRef(function (_ref3, ref) { var children = _ref3.children, loading = _ref3.loading, arrow = _ref3.arrow, iconBefore = _ref3.iconBefore, iconAfter = _ref3.iconAfter, disabled = _ref3.disabled, _ref3$intent = _ref3.intent, intent = _ref3$intent === void 0 ? 'primary' : _ref3$intent, _ref3$variant = _ref3.variant, variant = _ref3$variant === void 0 ? 'default' : _ref3$variant, _ref3$size = _ref3.size, size = _ref3$size === void 0 ? 'medium' : _ref3$size, props = _objectWithoutProperties(_ref3, ["children", "loading", "arrow", "iconBefore", "iconAfter", "disabled", "intent", "variant", "size"]); var _useFela = (0, _reactFela.useFela)(), theme = _useFela.theme; var styleProps = { disabled: disabled, intent: intent, variant: variant, loading: loading, size: size, theme: theme, arrow: arrow }; (0, _deprecate.deprecate)('intent=primary-light deprecated, use dark theme instead', intent === 'primary-light'); (0, _deprecate.deprecate)('iconBefore deprecated, use Icon component and pass as child', iconBefore); (0, _deprecate.deprecate)('iconAfter deprecated, use Icon component and pass as child', iconAfter); (0, _deprecate.deprecate)('Arrow deprecated, arrows will no longer be part of new button component design', arrow); return _react.default.createElement(_click.Click, _extends({ ref: ref }, props, { disabled: disabled || loading, extend: [button(styleProps), (0, _getThemeStyle.getThemeStyle)('button', theme, styleProps)] }), loading && _react.default.createElement(_block.Block, { extend: { position: 'absolute', margin: '0 auto' } }, _react.default.createElement(_spinner.Spinner, { color: "inherit", size: theme.baselineGrid * 4 })), loading ? _react.default.createElement(_inline.Inline, { extend: { visibility: 'hidden' } }, _react.default.createElement(InnerButton, { iconBefore: iconBefore, iconAfter: iconAfter, arrow: arrow }, children)) : _react.default.createElement(InnerButton, { iconBefore: iconBefore, iconAfter: iconAfter, arrow: arrow }, children)); }); exports.Button = Button; var InnerButton = function InnerButton(_ref4) { var children = _ref4.children, iconBefore = _ref4.iconBefore, iconAfter = _ref4.iconAfter, arrow = _ref4.arrow; return _react.default.createElement(_react.default.Fragment, null, iconBefore && _react.default.createElement(_inline.Inline, { extend: { marginRight: 12, position: 'relative', bottom: '-3px' } }, _react.default.createElement(_icon.Icon, { size: "m", type: iconBefore })), arrow && arrow === 'left' && _react.default.createElement(_inline.Inline, { extend: { marginRight: 8 } }, _react.default.createElement(_arrow.Arrow, { direction: 'left' })), children, arrow && arrow !== 'left' && _react.default.createElement(_inline.Inline, { extend: { marginLeft: 8 } }, _react.default.createElement(_arrow.Arrow, { direction: arrow })), iconAfter && _react.default.createElement(_inline.Inline, { extend: { marginLeft: 12, position: 'relative', bottom: '-3px' } }, _react.default.createElement(_icon.Icon, { size: "m", type: iconAfter }))); }; Button.displayName = 'Button'; Button.propTypes = { /** A JSX node */ children: _propTypes.default.node, intent: _propTypes.default.oneOf(['primary', 'primary-light', // deprecated 'secondary', 'destructive']), variant: _propTypes.default.oneOf(['default', 'outline', 'text']), loading: _propTypes.default.bool, disabled: _propTypes.default.bool, arrow: _propTypes.default.oneOf(['up', 'down', 'right', 'left']), /** Add an icon before button text */ iconBefore: _propTypes.default.string, /** Add an icon after button text */ iconAfter: _propTypes.default.string, /** Changes the rendered element from `<button>` to `<a>` */ href: _propTypes.default.string, size: _propTypes.default.oneOf(['small', 'medium', 'large']) };