2022-08-18 19:51:53 +02:00
|
|
|
import React from 'react';
|
|
|
|
import classnames from 'classnames';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import Box from '../../ui/box';
|
|
|
|
import {
|
|
|
|
FONT_WEIGHT,
|
|
|
|
FONT_STYLE,
|
2023-02-02 21:15:26 +01:00
|
|
|
TextVariant,
|
2022-08-18 19:51:53 +02:00
|
|
|
TEXT_ALIGN,
|
|
|
|
TEXT_TRANSFORM,
|
|
|
|
OVERFLOW_WRAP,
|
2023-02-02 21:15:26 +01:00
|
|
|
TextColor,
|
2022-08-18 19:51:53 +02:00
|
|
|
} from '../../../helpers/constants/design-system';
|
2023-02-10 01:09:33 +01:00
|
|
|
import { TEXT_DIRECTIONS } from './text.constants';
|
2022-08-18 19:51:53 +02:00
|
|
|
|
|
|
|
export const ValidTags = [
|
|
|
|
'dd',
|
|
|
|
'div',
|
|
|
|
'dt',
|
|
|
|
'em',
|
|
|
|
'h1',
|
|
|
|
'h2',
|
|
|
|
'h3',
|
|
|
|
'h4',
|
|
|
|
'h5',
|
|
|
|
'h6',
|
|
|
|
'li',
|
|
|
|
'p',
|
|
|
|
'span',
|
|
|
|
'strong',
|
|
|
|
'ul',
|
|
|
|
'label',
|
2022-10-04 19:05:55 +02:00
|
|
|
'input',
|
2022-08-18 19:51:53 +02:00
|
|
|
];
|
|
|
|
|
2023-02-22 18:41:46 +01:00
|
|
|
const getTextElementDefault = (variant) => {
|
|
|
|
switch (variant) {
|
|
|
|
case TextVariant.displayMd:
|
|
|
|
return 'h1';
|
|
|
|
case TextVariant.headingLg:
|
|
|
|
return 'h2';
|
|
|
|
case TextVariant.headingMd:
|
|
|
|
return 'h3';
|
|
|
|
case TextVariant.headingSm:
|
|
|
|
return 'h4';
|
|
|
|
case TextVariant.inherit:
|
|
|
|
return 'span';
|
|
|
|
// TextVariant.bodyLgMedium, TextVariant.bodyMd, TextVariant.bodyMdBold, TextVariant.bodySm, TextVariant.bodySmBold, TextVariant.bodyXs use default 'p' tag
|
|
|
|
default:
|
|
|
|
return 'p';
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-10-04 19:05:55 +02:00
|
|
|
export const Text = React.forwardRef(
|
|
|
|
(
|
2022-08-18 19:51:53 +02:00
|
|
|
{
|
2023-02-02 21:15:26 +01:00
|
|
|
variant = TextVariant.bodyMd,
|
|
|
|
color = TextColor.textDefault,
|
2022-10-04 19:05:55 +02:00
|
|
|
fontWeight,
|
|
|
|
fontStyle,
|
|
|
|
textTransform,
|
|
|
|
textAlign,
|
2022-12-15 19:49:47 +01:00
|
|
|
textDirection,
|
2022-10-04 19:05:55 +02:00
|
|
|
overflowWrap,
|
|
|
|
ellipsis,
|
|
|
|
as,
|
|
|
|
className,
|
|
|
|
children,
|
|
|
|
...props
|
2022-08-18 19:51:53 +02:00
|
|
|
},
|
2022-10-04 19:05:55 +02:00
|
|
|
ref,
|
|
|
|
) => {
|
2023-02-22 18:41:46 +01:00
|
|
|
// Check if as is set otherwise set a default tag based on variant
|
|
|
|
const Tag = as ?? getTextElementDefault(variant);
|
2022-10-04 19:05:55 +02:00
|
|
|
let strongTagFontWeight;
|
2022-08-18 19:51:53 +02:00
|
|
|
|
2022-10-04 19:05:55 +02:00
|
|
|
if (Tag === 'strong') {
|
|
|
|
strongTagFontWeight = FONT_WEIGHT.BOLD;
|
|
|
|
}
|
2022-08-18 19:51:53 +02:00
|
|
|
|
2022-10-04 19:05:55 +02:00
|
|
|
const computedClassName = classnames(
|
2022-12-01 18:26:19 +01:00
|
|
|
'mm-text',
|
2022-10-04 19:05:55 +02:00
|
|
|
className,
|
2022-12-01 18:26:19 +01:00
|
|
|
`mm-text--${variant}`,
|
2022-10-04 19:05:55 +02:00
|
|
|
(strongTagFontWeight || fontWeight) &&
|
2022-12-01 18:26:19 +01:00
|
|
|
`mm-text--font-weight-${strongTagFontWeight || fontWeight}`,
|
2022-10-04 19:05:55 +02:00
|
|
|
{
|
2022-12-01 18:26:19 +01:00
|
|
|
[`mm-text--font-style-${fontStyle}`]: Boolean(fontStyle),
|
|
|
|
[`mm-text--ellipsis`]: Boolean(ellipsis),
|
|
|
|
[`mm-text--text-transform-${textTransform}`]: Boolean(textTransform),
|
|
|
|
[`mm-text--text-align-${textAlign}`]: Boolean(textAlign),
|
|
|
|
[`mm-text--color-${color}`]: Boolean(color),
|
|
|
|
[`mm-text--overflow-wrap-${overflowWrap}`]: Boolean(overflowWrap),
|
2022-10-04 19:05:55 +02:00
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Box
|
|
|
|
ref={ref}
|
|
|
|
className={classnames(computedClassName)}
|
|
|
|
as={Tag}
|
2022-12-15 19:49:47 +01:00
|
|
|
dir={textDirection}
|
2022-10-04 19:05:55 +02:00
|
|
|
{...props}
|
|
|
|
>
|
|
|
|
{children}
|
|
|
|
</Box>
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
2022-08-18 19:51:53 +02:00
|
|
|
|
|
|
|
Text.propTypes = {
|
|
|
|
/**
|
2022-12-01 18:26:19 +01:00
|
|
|
* The variation of font styles including sizes and weights of the Text component
|
|
|
|
* Possible values:
|
|
|
|
* `DISPLAY_MD` large screen: 48px / small screen: 32px,
|
|
|
|
* `HEADING_LG` large screen: 32px / small screen: 24px,
|
|
|
|
* `HEADING_MD` large screen: 24px / small screen: 18px,
|
|
|
|
* `HEADING_SM` large screen: 18px / small screen: 16px,
|
|
|
|
* `BODY_LG_MEDIUM` large screen: 18px / small screen: 16px,
|
|
|
|
* `BODY_MD` large screen: 16px / small screen: 14px,
|
|
|
|
* `BODY_MD_BOLD` large screen: 16px / small screen: 14px,
|
|
|
|
* `BODY_SM` large screen: 14px / small screen: 12px,
|
|
|
|
* `BODY_SM_BOLD` large screen: 14px / small screen: 12px,
|
|
|
|
* `BODY_XS` large screen: 12px / small screen: 10px,
|
|
|
|
* `INHERIT`
|
2022-08-18 19:51:53 +02:00
|
|
|
*/
|
2023-02-10 01:09:33 +01:00
|
|
|
variant: PropTypes.oneOf(Object.values(TextVariant)),
|
2022-08-18 19:51:53 +02:00
|
|
|
/**
|
|
|
|
* The color of the Text component Should use the COLOR object from
|
|
|
|
* ./ui/helpers/constants/design-system.js
|
|
|
|
*/
|
2023-02-02 21:15:26 +01:00
|
|
|
color: PropTypes.oneOf(Object.values(TextColor)),
|
2022-08-18 19:51:53 +02:00
|
|
|
/**
|
|
|
|
* The font-weight of the Text component. Should use the FONT_WEIGHT object from
|
|
|
|
* ./ui/helpers/constants/design-system.js
|
|
|
|
*/
|
|
|
|
fontWeight: PropTypes.oneOf(Object.values(FONT_WEIGHT)),
|
|
|
|
/**
|
|
|
|
* The font-style of the Text component. Should use the FONT_STYLE object from
|
|
|
|
* ./ui/helpers/constants/design-system.js
|
|
|
|
*/
|
|
|
|
fontStyle: PropTypes.oneOf(Object.values(FONT_STYLE)),
|
|
|
|
/**
|
|
|
|
* The textTransform of the Text component. Should use the TEXT_TRANSFORM object from
|
|
|
|
* ./ui/helpers/constants/design-system.js
|
|
|
|
*/
|
|
|
|
textTransform: PropTypes.oneOf(Object.values(TEXT_TRANSFORM)),
|
|
|
|
/**
|
|
|
|
* The text-align of the Text component. Should use the TEXT_ALIGN object from
|
|
|
|
* ./ui/helpers/constants/design-system.js
|
|
|
|
*/
|
|
|
|
textAlign: PropTypes.oneOf(Object.values(TEXT_ALIGN)),
|
2022-12-15 19:49:47 +01:00
|
|
|
/**
|
|
|
|
* Change the dir (direction) global attribute of text to support the direction a language is written
|
|
|
|
* Possible values: `LEFT_TO_RIGHT` (default), `RIGHT_TO_LEFT`, `AUTO` (user agent decides)
|
|
|
|
*/
|
|
|
|
textDirection: PropTypes.oneOf(Object.values(TEXT_DIRECTIONS)),
|
2022-08-18 19:51:53 +02:00
|
|
|
/**
|
|
|
|
* The overflow-wrap of the Text component. Should use the OVERFLOW_WRAP object from
|
|
|
|
* ./ui/helpers/constants/design-system.js
|
|
|
|
*/
|
|
|
|
overflowWrap: PropTypes.oneOf(Object.values(OVERFLOW_WRAP)),
|
|
|
|
/**
|
|
|
|
* Used for long strings that can be cut off...
|
|
|
|
*/
|
|
|
|
ellipsis: PropTypes.bool,
|
|
|
|
/**
|
|
|
|
* Changes the root html element tag of the Text component.
|
|
|
|
*/
|
|
|
|
as: PropTypes.oneOf(ValidTags),
|
|
|
|
/**
|
|
|
|
* Additional className to assign the Text component
|
|
|
|
*/
|
|
|
|
className: PropTypes.string,
|
|
|
|
/**
|
|
|
|
* The text content of the Text component
|
|
|
|
*/
|
|
|
|
children: PropTypes.node.isRequired,
|
|
|
|
/**
|
|
|
|
* Text component accepts all Box component props
|
|
|
|
*/
|
|
|
|
...Box.propTypes,
|
|
|
|
};
|
|
|
|
|
2022-10-04 19:05:55 +02:00
|
|
|
Text.displayName = 'Text'; // Used for React DevTools profiler
|