vcc-ui
Version:
A React library for building user interfaces at Volvo Cars
90 lines (88 loc) • 3.44 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import PropTypes from 'prop-types';
import React, { useContext } from 'react';
import { useFela } from 'react-fela';
import { responsiveStringProp } from '../../utils/prop-types-utils';
import { Click } from '../click';
import { getRenderedElement, mergeStyles, normalizeResponsiveValue } from './utils';
export const SUB_STYLES = ['standard', 'inline-link', 'emphasis'];
const TextContext = /*#__PURE__*/React.createContext({
isRootElement: true
});
const defaultVariant = 'columbus';
const defaultSubStyle = 'standard';
/**
* @deprecated Use proper semantic elements instead like heading, paragraph, etc. See [Typography](https://developer.volvocars.com/design-system/web/?path=/docs/typography-introduction--docs)
*/
export const Text = /*#__PURE__*/React.forwardRef((_ref, ref) => {
let {
extend,
variant,
subStyle,
fg,
foreground = fg,
as,
className,
children,
...props
} = _ref;
const {
css,
theme
} = useFela(props);
const {
isRootElement,
parentVariant,
parentSubStyle
} = useContext(TextContext);
const appliedVariant = variant || parentVariant || defaultVariant;
const appliedSubStyle = subStyle || parentSubStyle || defaultSubStyle;
const variants = normalizeResponsiveValue(appliedVariant);
const subStyles = normalizeResponsiveValue(appliedSubStyle);
const displayModifier = isRootElement ? {
display: 'block'
} : {};
let Element = getRenderedElement(isRootElement, as, appliedVariant, appliedSubStyle, theme);
if (Element === 'a') {
Element = Click;
}
return /*#__PURE__*/React.createElement(Element, _extends({
ref: ref
}, props, {
className: css(displayModifier, {
color: foreground || theme.color.foreground.primary,
margin: 0,
...mergeStyles(theme.typeScale[variants[0]], subStyles[0], ''),
fromM: mergeStyles(theme.typeScale[variants[1]], subStyles[1], 'fromM'),
fromL: mergeStyles(theme.typeScale[variants[2]], subStyles[2], 'fromL'),
fromXL: mergeStyles(theme.typeScale[variants[3]], subStyles[3], 'fromXL')
}, extend) + (className ? ' ' + className : '')
}), /*#__PURE__*/React.createElement(TextContext.Provider, {
value: {
isRootElement: false,
parentVariant: appliedVariant,
parentSubStyle: appliedSubStyle
}
}, children));
});
// @ts-ignore
Text.displayName = 'Text';
// @ts-ignore
Text.propTypes = {
/** A JSX node */
children: PropTypes.node,
/** A custom font color */
fg: responsiveStringProp,
/** A custom font color */
foreground: responsiveStringProp,
/** Any valid React element, function, or a string specifying a name for an HTML element */
as: PropTypes.oneOfType([PropTypes.string, PropTypes.element, PropTypes.elementType, PropTypes.func]),
/** One of the available type scale styles */
variant: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.string]),
/** One of the available sub-styles for a given type scale */
subStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array, 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
};