今回はstyled-componentsを主題に話しますが、構文の使えないJSX内でも同じことが言えます。
styled-componentsを使ってて、どうしても冗長になりがちなのでああだこうだしました。
設定
適当御免
react: 16.12.0
styled-components: 4.4.1
GlobalStyles.js
import { createGlobalStyle } from 'styled-components';
export default createGlobalStyle`...`;
export const theme = {
color: {
primary: "#5535E8",
primaries: {
main: "#5535E8",
base: "#3B4DFF",
accent: "#FE3BFF"
}
}
};
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>
};
};
// 以下、インポート省略
import React from 'react';
import styled, { css } from 'styled-components';
##propsって書きたくない
// 公式
const Button = styled.div`
background-color: ${props => props.backgroundColor};
color: ${props => props.theme.color.primary};
`;
// ✌️
const Button = styled.div`
${({backgroundColor, theme}) => css`
background-color: ${backgroundColor};
color: ${theme.color.primary};
`}`;
// さらに楽をしたい
const Button = styled.div`
${({backgroundColor, theme}) => ({theme: {color}}) => css`
background-color: ${backgroundColor};
color: ${color.primary};
`}`;
##エクスポート時にstyled
const Button = ({
onClick,
className,
children
}) => {
return {
<button
{/* ここにstyledが注入される */}
className={className}
onClick={onClick}
>
{children}
</button>
}
};
export default styled(Button)``;
and | or | switch
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; `
}
`}`;
// よくやるやつ
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}; `}
`}`;
// できたらいいのに
${["red". "blue", "green"].map(item => {
(types === item) && css`
color: ${item};
`;
})}
themeの色を使う
Parent.js
const Parent = () => {
reuturn {
<Child1 Color="primary" />
<Child2 Color="primaries" />
}
}
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};
`}`;
##隙のない3段構え
theme指定→カラーコード指定→デフォルト
export const Button = styled.div`
${({Color, theme}) => ({theme: {color}}) css`
background-color: ${
color[Color] || Color || "#ddd"
};
`}`;