[CSS in JS] styled関数で受け取るpropsを短く書く方法
概要
CSS in JS で実装されているstyled関数では、テンプレートリテラルを使ってスタイルを定義できる。
const Button = styled.button`
color: #bf4f74;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid #bf4f74;
border-radius: 3px;
`;
このとき、コンテキストの情報を${(props) => props.theme.primaryColor}
のように参照できる。
ただ、複雑になってくると記述が複雑になって可読性が下がる課題もある。
propsの参照
Styledコンポーネントでは、コンポーネントに渡されたprops
オブジェクトから必要な情報を取り出して、スタイリングに反映させることができる。
以下のコード例では、props
オブジェクトからisPrimary
の値を取り出し、動的にスタイルを定義している。
const Button = styled.button<{ isPrimary?: boolean }>`
background: ${(props) => (props.isPrimary ? '#BF4F74' : 'white')};
color: ${(props) => (props.isPrimary ? 'white' : '#BF4F74')};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid #bf4f74;
border-radius: 3px;
`;
Note
${(props) => props.theme.primaryColor}
のような部分をinterpolationsと呼ばれている。
https://styled-components.com/docs/advanced
書き方
基本的な書き方であれば下記のようになる。${(props) => props.xxx}
のようにprops
を引数として受け取り参照する。
const Button = styled.button<{ isPrimary?: boolean }>`
background: ${(props) => (props.isPrimary ? '#BF4F74' : 'white')};
color: ${(props) => (props.isPrimary ? 'white' : '#BF4F74')};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid #bf4f74;
border-radius: 3px;
`;
スプレッド構文でpropsを展開する
引数のprops
を展開しておくことで短めに書くことができる。
const Button = styled.button<{ isPrimary?: boolean }>`
background: ${({ isPrimary }) => (isPrimary ? '#BF4F74' : 'white')};
color: ${({ isPrimary }) => (isPrimary ? 'white' : '#BF4F74')};
// ...
`;
ただ、この書き方はprops
の中身が増えると可読性が下がる。
例:${({ theme, isPrimary, isSecondary }) => ...}
styledのコールバックでpropsを受け取る
大元でprops
を受けることで各プロパティ毎の参照を減らすことができる。
const Button = styled.button<{ isPrimary?: boolean }>(
(props) => `
background: ${props.isPrimary ? '#BF4F74' : 'white'};
color: ${props.isPrimary ? 'white' : '#BF4F74'};
// ...
`,
);
エディタによってはシンタックスハイライトが効かない
Emotionであればcss関数があり、それをハイライトの対象としているエディタ(プラグイン)もあるので、以下のようにcss関数に変更することでハイライトを有効にできるケースがある。
const Button = styled.button<{ isPrimary?: boolean }>(
(props) => css`
background: ${props.isPrimary ? '#BF4F74' : 'white'};
color: ${props.isPrimary ? 'white' : '#BF4F74'};
// ...
`,
);
スプレッド構文の組み合わせでより短く書くこともできる。
const Button = styled.button<{ isPrimary?: boolean }>(
({ isPrimary }) => `
background: ${isPrimary ? '#BF4F74' : 'white'};
color: ${isPrimary ? 'white' : '#BF4F74'};
// ...
`,
);