0

In my project, I have a Text component:

import React from 'react'
import { bool, string, number, element, func, object, any } from 'prop-types'
import cx from 'classnames'
import s from './styles/Text.css'


const Text = (props) => {
  const renderMultiLines = () => {
    const items = props.children.split(' ')
    return items.map(text => <div style={{ marginBottom: '2px' }} className={s.multiLineItem}>{text}</div>)
  }

  return (
    <div
      className={cx(
        s.text,
        props.ellipsis && s.ellipsis,
        props.isUpperCase && s.isUpperCase,
        props.isBold && s.bold,
        props.isExtraBold && s.extraBold,
        props.isExtraSpaced && s.extraSpaced,
        props.multiLine && s.multiLine,
        props.active && s.underlined,
        props.active && s.primary,
        s[props.color],
        s[props.size],
      )}
      onClick={props.onClick}
      style={props.style}
    >
      {!props.multiLine && props.children}
      {props.multiLine && renderMultiLines()}
    </div>
  )
}

Text.defaultProps = {
  isBold: false,
  isExtraSpaced: false,
  isExtraBold: false,
  children: '',
  color: '',
  ellipsis: false,
  size: 'extraExtraSmall',
  isUpperCase: false,
  onClick: undefined,
  style: {},
  active: false,
}

Text.propTypes = {
  isBold: bool,
  isExtraSpaced: bool,
  isExtraBold: bool,
  children: any,
  color: string,
  ellipsis: bool,
  size: string,
  isUpperCase: bool,
  onClick: func,
  style: object,
  active: bool,
}

export default Text

As you can see, the intention is that you pass in props to change the layout of the text.

The idea is that you only ever end up with a limited amount of styles for text, and you never end up with slight variations.

An example of the usage of this component in my project looks like this:

<Text
  onClick={() => this.handleGlobalChangeDate(Number(n))}
  isBold
  size="medium"
  color="primary"
  active={Number(n) === activeDay && visibleMonth === activeMonth}
>{n}</Text>

This looks messy, and I feel like isBold, size, color etc should not need to be displayed here and passed in as props. Rather, they should be handled in the CSS and refer to the project's variables.css file.

In this way I would like to be able to attach a className to the Text component in question.

However, because it's a component and not simply a div, for example, the className would merely get passed to the component as a prop.

How can I use CSS to deal with this issue instead of using a multitude of style-related props?

alanbuchanan
  • 3,993
  • 7
  • 41
  • 64

1 Answers1

0

Try classnames, a great way to add classes dynamically based upon props or state.

With this you can do:

var btnClass = classNames({
  btn: true,
  'btn-pressed': this.state.isPressed,
  'btn-over': !this.state.isPressed && this.state.isHovered
});
return <button className={btnClass}>{this.props.label}</button>;

Then apply in your component:

<div className={btnClass}>Something</div>
Toby
  • 12,743
  • 8
  • 43
  • 75