У меня есть этот компонент всплывающей подсказки, и в данный момент он кажется довольно грязным и неоправданно многословным.У меня есть некоторые грубые идеи, но я не уверен, как их выполнить. Я считаю, что направления стрелок могут быть перенесены в класс, и я использую это для управления темой.то есть использование селектора потомков для применения правил 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;
}
}