React-将组件包装在一个类中,并使用它来控制主题化(减少冗长)

时间:2019-05-10 13:02:00

标签: reactjs css-selectors

我有这个工具提示组件,此刻它看起来很杂乱,看起来不必要地冗长。我有一些粗略的想法,但不确定如何执行。我相信箭头方向可以包装在一个类中,并使用它来控制主题。即使用后代选择器应用主题特定的CSS规则。我应该如何处理?

以下是组件:

import React, { Component } from 'react';
import { Manager, Reference, Popper } from 'react-popper';

import cx from 'classnames';
import css from './Tooltip.css';
import animationsCss from './TooltipAnimations.css';

class Tooltip extends Component {
  static defaultProps = {
    theme: 'light',
    eventsEnabled: true,
  };

  firstOrderPlacement(placement) {
    if (!placement) return null;
    return placement.split('-')[0];
  }

  arrowDirectionClass(firstOrderPlacement) {
    const { theme } = this.props;

    switch (firstOrderPlacement) {
      case 'right':
        return cx(css.arrowLeft, theme === 'dark' ? css.arrowLeftDark : css.arrowLeftLight);
      case 'left':
        return cx(css.arrowRight, theme === 'dark' ? css.arrowRightDark : css.arrowRightLight);
      case 'top':
        return cx(css.arrowDown, theme === 'dark' ? css.arrowDownDark : css.arrowDownLight);
      case 'bottom':
        return cx(css.arrowUp, theme === 'dark' ? css.arrowUpDark : css.arrowUpLight);
      default:
        return cx(css.arrowUp, theme === 'dark' ? css.arrowUpDark : css.arrowUpLight);
    }
  }

  render() {
    const { placement, className, children, fadeIn, theme, eventsEnabled } = this.props;

    return (
      <Popper placement={placement} eventsEnabled={eventsEnabled}>
        {({ ref, style, placement }) => {
          const firstOrderPlacement = this.firstOrderPlacement(placement);
          const arrowDirectionClass = this.arrowDirectionClass(firstOrderPlacement);
          const subContainerStyle = {
            display: 'flex',
            flexDirection:
              firstOrderPlacement === 'top' || firstOrderPlacement === 'bottom' ? 'column' : 'row',
          };
          const childrenContainerClassName = cx(
            css.childrenContainer,
            theme === 'dark' ? css.backgroundDark : css.backgroundLight,
          );
          const content = <div className={childrenContainerClassName}>{children}</div>;
          const subContainerClassName = fadeIn ? cx(animationsCss.fadeIn, className) : className;

          return (
            <div
              ref={ref}
              className={cx(css.container, css.mobileTooltip)}
              style={style}
              data-placement={placement}
            >
              <div className={subContainerClassName} style={subContainerStyle}>
                {(firstOrderPlacement === 'left' || firstOrderPlacement === 'top') && content}
                <div>
                  <div className={cx(css.arrow, arrowDirectionClass)} />
                </div>
                {(firstOrderPlacement === 'right' || firstOrderPlacement === 'bottom') && content}
              </div>
            </div>
          );
        }}
      </Popper>
    );
  }
}

export { Manager as TooltipManager, Reference as TooltipReference, Tooltip };

这是CSS:

.container {
  z-index: 1;
}

.childrenContainer {
  box-shadow: 0 0.2rem 0.875rem 0.1rem rgba(0, 0, 0, 0.15);
  border-radius: 2px;
  flex: 1;
  line-height: 1.2;
  font-size: 0.85rem;
}

.backgroundLight {
  background: white;
  color: #262626;
}

.backgroundDark {
  background: #2d2d2d;
  color: #ffffff;
}

.arrow {
  position: relative;
  width: 0;
  height: 0;
}

.arrowRight {
  border-top: 0.4375rem solid transparent;
  border-bottom: 0.4375rem solid transparent;
}

.arrowRightLight {
  border-left: 0.4375rem solid var(--color-white);
}

.arrowRightDark {
  border-left: 0.4375rem solid #2d2d2d;
}

.arrowLeft {
  border-top: 0.4375rem solid transparent;
  border-bottom: 0.4375rem solid transparent;
}

.arrowLeftLight {
  border-right: 0.4375rem solid var(--color-white);
}

.arrowLeftDark {
  border-right: 0.4375rem solid #2d2d2d;
}

.arrowDown {
  margin: 0 auto;
  border-left: 0.4375rem solid transparent;
  border-right: 0.4375rem solid transparent;
}

.arrowDownLight {
  border-top: 0.4375rem solid var(--color-white);
}

.arrowDownDark {
  border-top: 0.4375rem solid #2d2d2d;
}

.arrowUp {
  margin: 0 auto;
  border-left: 0.4375rem solid transparent;
  border-right: 0.4375rem solid transparent;
}

.arrowUpLight {
  border-bottom: 0.4375rem solid var(--color-white);
}

.arrowUpDark {
  border-bottom: 0.4375rem solid #2d2d2d;
}

@media(max-width: 53.125rem) {
  .mobileTooltip {
    transform: none !important;
    top: -75px !important;
    left: 0;
    right: 0;
    margin: 5px;
  }

  .arrowDown {
    margin-left: auto;
    margin-right: 65px;
  }
}

0 个答案:

没有答案