styled-components Tips

今回はstyled-componentsを主題に話しますが、構文の使えないJSX内でも同じことが言えます。
styled-componentsを使ってて、どうしても冗長になりがちなのでああだこうだしました。

### 設定
適当御免
`react: 16.12.0`
`styled-components: 4.4.1`

```javascript:GlobalStyles.js
import { createGlobalStyle } from 'styled-components';

export default createGlobalStyle`...`;

export const theme = {
  color: {
    primary: "#5535E8",
    primaries: {
      main: "#5535E8",
      base: "#3B4DFF",
      accent: "#FE3BFF"
    }
  }
};
```
```javascript:Provider.js
import React from 'react';
import { ThemeProvider } from 'styled-components';
import GlobalStyle, { theme } from 'GlobalStyles';

export const Provider = ({children}) => {
  return {
    <ThemeProvider theme={theme}>
      <GlobalStyle />
      {children}
    </ThemeProvider>
  };
};

```
```javascript
// 以下、インポート省略
import React from 'react';
import styled, { css } from 'styled-components';
```

##propsって書きたくない
```javascript
// 公式
const Button = styled.div`
  background-color: ${props => props.backgroundColor};
  color: ${props => props.theme.color.primary};
`;
```


```javascript
// ✌️
const Button = styled.div`
${({backgroundColor, theme}) => css`
  background-color: ${backgroundColor};
  color: ${theme.color.primary};
`}`;
```
```javascript
// さらに楽をしたい
const Button = styled.div`
${({backgroundColor, theme}) => ({theme: {color}}) => css`
  background-color: ${backgroundColor};
  color: ${color.primary};
`}`;
```


##エクスポート時にstyled
```javascript
const Button = ({
  onClick,
  className,
  children
}) => {
  return {
    <button
      {/* ここにstyledが注入される */}
      className={className}
      onClick={onClick}
    >
        {children}
    </button>
  }
};

export default styled(Button)``;
```

## and | or | switch
```javascript
const Button = styled.div`
${({disable, textColor, Absolute, shadowColor}) => css`
  /* and */
  background-color: ${disable && "#ddd"};

  /* or */
  color: ${textColor || "#333"};
  /* a or b */
  position: ${Absolute ? "absolute" : "relative"};

  /* switch */
  ${shadowColor === "red"
  ? css` color: #fc1206; `
  : shadowColor === "blue"
  ? css` color: skyblue; `
  : shadowColor === "green"
  && css` color: green; `
  }
`}`;
```

```javascript
// よくやるやつ
const Positions = styled.div`
${({Top, Left, Right, Bottom}) => css`
  ${(Top || Left || Right || Bottom) && css`
    position: absolute;
  `}
  ${ Top && css` top: ${Top}; `}
  ${ Bottom && css` bottom: ${Bottom}; `}
  ${ Right && css` right: ${Right}; `}
  ${ Left && css` left: ${Left}; `}
`}`;
```
```javascript
// できたらいいのに
${["red". "blue", "green"].map(item => {
  (types === item) && css`
    color: ${item};
  `;
})}
```
## themeの色を使う
```javascript:Parent.js
const Parent = () => {
  reuturn {
    <Child1 Color="primary" />
    <Child2 Color="primaries" />
  }
}
```
```javascript:Child.js
// normal
export const Child1 = styled.div`
${({Color, theme}) => ({theme: {color}}) css`
  background-color: ${color[Color]};
`}`;
`// サブカラー設定時
export const Child2 = styled.div`
${({Color, theme}) => ({theme: {color}}) css`
  background-color: ${color[Color].main};
  color: ${color[Color].accent};
  box-shadow: 0 6px ${color[Color].base};
`}`;
```
##隙のない３段構え
theme指定→カラーコード指定→デフォルト

```javascript
export const Button = styled.div`
${({Color, theme}) => ({theme: {color}}) css`
  background-color: ${
    color[Color] || Color || "#ddd"
  };
`}`;
```