将样式化组件“原子”嵌套在“分子”中->样式/位置

时间:2019-11-22 10:14:28

标签: javascript css reactjs typescript styled-components

我需要创建一个React组件库

为此,我将React与Typescript和样式化组件一起使用。

当我尝试在分子中重用原子时,我被卡住了。

我这样创建我的Button Atom组件:

interface IButtonProps {
    text?: string
    onClick?: React.MouseEventHandler<HTMLButtonElement>
}

const StyledButton = styled.button<IButtonProps>`
  height: 70px;
  width: 70px;
  border: none;
  border-radius: 5px;
  background-color: #88BDBC;
  color: #254E58;
  font-family: Alata, sans-serif;
  font-size: 35px;
  transition: all 350ms;

  &:hover {
    background-color: #254E58;
    color: #88BDBC;
  }

  &:active {
    background-color: #112D32;
    color: #88BDBC;
  }
`;

const Button = ({
   text = "",
   onClick
}: IButtonProps): React.ReactElement => {
    return (
        <StyledButton onClick={onClick}>{text}</StyledButton>
    );
};

对于我的Atom,这只是一个非常不完美的示例。我创建所有这样的Atom。我只在Atoms-> Colors,Borders,Margins等内部定义样式。不是外部样式->例如填充,然后我认为它很大程度上取决于使用此Button的上下文。

所以我非常精通。

当我想在“控制器”分子中使用Button时,我需要给该Button一些位置,也许还有一些填充等。

但是在我的父样式组件中,我现在不知道如何正确指向它们。尤其是当我像这里有更多的组件组合时。

interface IControllerProps {
    text1: string;
    text2: string;
    text3: string;
    onClick?: React.MouseEventHandler<HTMLButtonElement>
}

const StyledController = styled.div<IControllerProps>`
  /* ... */
`;

const Controller = ({
    onClick
}: IControllerProps) => {
    const [powerOn, setPowerOn] = React.useState(false);
    const [bankType, setBankType] = React.useState(false);
    const [volume, setVolume] = React.useState(50);

    return (
        <StyledController>
            <Text text="Hello"/>
            <Switch checked={powerOn} onChange={(e: React.ChangeEvent<HTMLInputElement>) => {setPowerOn(e.target.checked)}}/>
            <Button onClick={() => false}/>
            <Text text="Hello"/>
            <RangeSlider value={volume} min={0} max={100} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setVolume(parseInt(e.target.value))} />
            <Text text="Hello"/>
            <Switch checked={bankType} onChange={(e: React.ChangeEvent<HTMLInputElement>) => {setBankType(e.target.checked)}}/>
            <Button onClick={onClick}/>
            <Button onClick={onClick}/>
        </StyledController>
    )
};

我是否需要使用Propertys才能将其赋予按钮...用伪类指向所有内容...在Button中定义所有内容(但是灵活使用可重用Button的上下文)...

最佳做法是什么?

2 个答案:

答案 0 :(得分:1)

您可以像这样定位样式(我用JavaScript回答的原因是为了减少复杂性):

// Button.react.js
export const StyledButton = styled.button`
  background-color: #88bdbc;
`;

// Controller.react.js
import { StyledButton } from './Button.react.js';

const StyledController = styled.div`
  ${StyledButton} {
    background-color: blue;
  }
`;

请检查related docs

答案 1 :(得分:-1)

除了丹尼斯·瓦什的答案:

对于我的示例按钮组件,这意味着我需要像这样更改它:

interface IButtonProps {
    text?: string
    onClick?: React.MouseEventHandler<HTMLButtonElement>
    className?: string
}

const UnstyledButton = ({
    text = "",
    onClick,
    className
}: IButtonProps): React.ReactElement => {
    return (
        <button onClick={onClick} className={className}>{text}</button>
    );
};

const Button = styled(UnstyledButton)<IButtonProps>`
  height: 70px;
  width: 70px;
  border: none;
  border-radius: 5px;
  background-color: #88BDBC;
  color: #254E58;
  font-family: Alata, sans-serif;
  font-size: 35px;
  transition: all 350ms;

  &:hover {
    background-color: #254E58;
    color: #88BDBC;
  }

  &:active {
    background-color: #112D32;
    color: #88BDBC;
  }
`;

原因是:这仅在样式化组件的上下文中有效,而在ReactElement的上下文中无效。

样式化组件文档中的重要点: 但是,在styled()工厂中包装使其可以进行插值-只需确保包装的组件沿className传递即可。

当您直接从样式化组件中使用按钮(如提到的Dannis Vash)时,您可以直接引用它。