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.
149 lines (129 loc) • 6.57 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 _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
import React from 'react';
import { useFela } from 'react-fela';
import { objectMap } from '../../object-map';
import { renameKeys } from '../../rename-keys';
import PropTypes from 'prop-types';
export var SUB_STYLES = ['standard', 'inline-link', 'emphasis', 'overline'];
export var convertBaselineValues = objectMap(function (value, key) {
if (key === 'top') {
return "".concat(value, "px 0 0");
} else if (key === 'bottom') {
return "0 0 ".concat(value, "px");
}
if (_typeof(value) === 'object') {
return convertBaselineValues(value);
}
return value;
});
export var renameBaselineKeys = renameKeys({
top: 'padding',
bottom: 'margin'
});
export var convertBaselineKeys = function convertBaselineKeys(obj) {
return renameBaselineKeys(objectMap(function (value) {
if (_typeof(value) === 'object') {
return renameBaselineKeys(value);
}
return value;
})(obj));
};
/**
Baseline adjustments allow us to fine tune each type scale
so it sits on the 4px baseline. It only needs to be applied to
the root element. We use a combination of margin and padding
to prevent margin collapsing.
*/
export var createBaselineAdjustments = function createBaselineAdjustments(_ref) {
var _ref$baselineAdjustme = _ref.baselineAdjustments,
baselineAdjustments = _ref$baselineAdjustme === void 0 ? {} : _ref$baselineAdjustme,
isRootElement = _ref.isRootElement,
shouldAdjustBaseline = _ref.shouldAdjustBaseline;
if (!shouldAdjustBaseline || !isRootElement) {
return {
margin: 0,
padding: 0
};
}
return convertBaselineKeys(convertBaselineValues(baselineAdjustments));
};
var TextContext = React.createContext();
export var Text = React.forwardRef(function (_ref2, ref) {
var extend = _ref2.extend,
userVariant = _ref2.variant,
subStyle = _ref2.subStyle,
_ref2$alignBaseline = _ref2.alignBaseline,
shouldAdjustBaseline = _ref2$alignBaseline === void 0 ? true : _ref2$alignBaseline,
as = _ref2.as,
className = _ref2.className,
children = _ref2.children,
props = _objectWithoutProperties(_ref2, ["extend", "variant", "subStyle", "alignBaseline", "as", "className", "children"]);
var _useFela = useFela(props),
css = _useFela.css,
theme = _useFela.theme;
/**
Context is used for two reasons:
1. Allows us to derive the type scale from the context, letting us omit
the variant name for nested styles, eg:
<Text variant="columbus">Hello <Text subStyle="bold">World</Text></Text>
2. Lets us know if the element is the 'root' element, and apply baseline
adjustments if required.
*/
return React.createElement(TextContext.Consumer, null, function () {
var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref3$parentVariant = _ref3.parentVariant,
variant = _ref3$parentVariant === void 0 ? userVariant : _ref3$parentVariant,
_ref3$isRootElement = _ref3.isRootElement,
isRootElement = _ref3$isRootElement === void 0 ? true : _ref3$isRootElement;
var typeScaleStyle = theme.typeScale[variant];
var _typeScaleStyle$subSt = typeScaleStyle[subStyle],
preferredElement = _typeScaleStyle$subSt.element,
styles = _typeScaleStyle$subSt.styles,
baselineAdjustments = _typeScaleStyle$subSt.baselineAdjustments;
var baselineAdjustmentStyles = createBaselineAdjustments({
baselineAdjustments: baselineAdjustments,
isRootElement: isRootElement,
shouldAdjustBaseline: shouldAdjustBaseline
});
var displayModifier = isRootElement ? {
display: 'block'
} : {};
var Element = as || preferredElement || 'p';
return React.createElement(Element, _extends({
ref: ref
}, props, {
className: css({
color: theme.color.foreground.primary
}, displayModifier, styles, baselineAdjustmentStyles, extend) + (className ? ' ' + className : '')
}), React.createElement(TextContext.Provider, {
value: {
parentVariant: variant,
isRootElement: false
}
}, children));
});
});
Text.displayName = 'Text';
Text.defaultProps = {
variant: 'columbus',
subStyle: 'standard'
};
Text.propTypes = {
/** A JSX node */
children: PropTypes.node,
/** Any valid React element, function, or a string specifying a name for an HTML element */
as: PropTypes.oneOfType([PropTypes.string, PropTypes.element, PropTypes.func]),
/** One of the available type scale styles */
variant: PropTypes.string,
/** One of the available sub-styles for a given type scale */
subStyle: PropTypes.string,
/** An object containing valid CSS style declarations */
extend: PropTypes.oneOfType([PropTypes.object, PropTypes.func, PropTypes.array]),
/** Add an additional custom className to element. Warning: make sure it doesn't collide with the classNames being generated for the atomic CSS */
className: PropTypes.string,
/** Adjust padding-top/margin-bottom to the text to keep it aligned with the micro grid. */
alignBaseline: PropTypes.bool
};