gab-social/app/javascript/gabsocial/components/text.js

140 lines
3.5 KiB
JavaScript
Raw Normal View History

import React from 'react'
import PropTypes from 'prop-types'
2020-02-19 23:57:07 +00:00
import classNames from 'classnames/bind'
2020-04-23 07:13:29 +01:00
// Bind CSS Modules global variable `_s` to classNames module
2020-02-19 23:57:07 +00:00
const cx = classNames.bind(_s)
2020-04-23 07:13:29 +01:00
// Define colors for enumeration for Text component `color` prop
2020-02-19 23:57:07 +00:00
const COLORS = {
primary: 'primary',
secondary: 'secondary',
2020-04-17 06:35:46 +01:00
tertiary: 'tertiary',
2020-02-19 23:57:07 +00:00
brand: 'brand',
error: 'error',
white: 'white',
2020-02-21 00:57:29 +00:00
inherit: 'inherit',
2020-02-19 23:57:07 +00:00
}
2020-04-23 07:13:29 +01:00
// Define sizes for enumeration for Text component `size` prop
2020-02-19 23:57:07 +00:00
const SIZES = {
extraSmall: 'extraSmall',
small: 'small',
normal: 'normal',
medium: 'medium',
large: 'large',
extraLarge: 'extraLarge',
extraExtraLarge: 'extraExtraLarge',
2020-02-19 23:57:07 +00:00
}
2020-04-23 07:13:29 +01:00
// Define weights for enumeration for Text component `weight` prop
2020-02-19 23:57:07 +00:00
const WEIGHTS = {
normal: 'normal',
medium: 'medium',
bold: 'bold',
extraBold: 'extraBold',
}
2020-04-23 07:13:29 +01:00
// Define alignments for enumeration for Text component `align` prop
2020-02-21 00:57:29 +00:00
const ALIGNMENTS = {
center: 'center',
left: 'left',
}
2020-04-23 07:13:29 +01:00
/**
* Renders a text component
* @param {string} [props.align='left] - the alignment of the text
* @param {bool} [props.isBadge] - to style the text as a badge
* @param {string} [props.className] - add custom className
* @param {string} [props.color='primary'] color of the text
* @param {bool} [props.hasUnderline] - if the text is underlined
* @param {string} [props.htmlFor] - define the `for` attribute on the tag
* @param {string} [props.size='normal'] size of the text
* @param {string} [props.tagName='span'] tagName of the text element
* @param {string} [props.weight='normal'] weight of the text
*/
class Text extends React.PureComponent {
2020-02-19 23:57:07 +00:00
render() {
2020-02-21 00:57:29 +00:00
const {
tagName,
className,
children,
color,
size,
weight,
2020-03-26 03:11:32 +00:00
align,
2020-04-02 04:17:21 +01:00
htmlFor,
2020-04-23 07:13:29 +01:00
isBadge,
hasUnderline,
2020-02-21 00:57:29 +00:00
} = this.props
2020-02-19 23:57:07 +00:00
2020-04-23 07:13:29 +01:00
// Style the component according to props
2020-02-19 23:57:07 +00:00
const classes = cx(className, {
d: 1,
2020-02-19 23:57:07 +00:00
text: 1,
2020-04-23 07:13:29 +01:00
radiusSmall: isBadge,
lineHeight15: isBadge,
px5: isBadge,
2020-04-02 04:17:21 +01:00
cPrimary: color === COLORS.primary,
cSecondary: color === COLORS.secondary,
cTertiary: color === COLORS.tertiary,
cBrand: color === COLORS.brand,
cWhite: color === COLORS.white,
2020-02-21 00:57:29 +00:00
inherit: color === COLORS.inherit,
fs24PX: size === SIZES.extraExtraLarge,
fs19PX: size === SIZES.extraLarge,
fs16PX: size === SIZES.large,
2020-04-29 23:32:49 +01:00
fs15PX: size === SIZES.medium,
fs14PX: size === SIZES.normal,
fs13PX: size === SIZES.small,
fs12PX: size === SIZES.extraSmall,
2020-02-19 23:57:07 +00:00
fw400: weight === WEIGHTS.normal,
fw500: weight === WEIGHTS.medium,
fw600: weight === WEIGHTS.bold,
fw800: weight === WEIGHTS.extraBold,
2020-02-21 00:57:29 +00:00
textAlignLeft: align === ALIGNMENTS.left,
textAlignCenter: align === ALIGNMENTS.center,
2020-02-19 23:57:07 +00:00
2020-04-23 07:13:29 +01:00
underline: hasUnderline,
2020-02-19 23:57:07 +00:00
})
return React.createElement(
tagName,
{
2020-03-26 03:11:32 +00:00
htmlFor,
2020-02-19 23:57:07 +00:00
className: classes,
},
children,
)
}
2020-04-23 07:13:29 +01:00
}
Text.propTypes = {
align: PropTypes.oneOf(Object.keys(ALIGNMENTS)),
isBadge: PropTypes.bool,
children: PropTypes.any,
className: PropTypes.string,
color: PropTypes.oneOf(Object.keys(COLORS)),
hasUnderline: PropTypes.bool,
htmlFor: PropTypes.string,
size: PropTypes.oneOf(Object.keys(SIZES)),
tagName: PropTypes.string,
weight: PropTypes.oneOf(Object.keys(WEIGHTS)),
}
Text.defaultProps = {
tagName: 'span',
align: ALIGNMENTS.left,
color: COLORS.primary,
size: SIZES.normal,
weight: WEIGHTS.normal,
}
export default Text