アジェンダ
Emotionは、強力なCSS-in-JSライブラリで、Reactコンポーネントにスタイルを簡単に適用できます。しかし、コンポーネント内にスタイルを直接定義するのではなく、スタイルを別ファイルに分けて管理したい場合があります。この記事では、Emotionを使ってスタイルを別ファイルに分離し、Reactコンポーネントに適用する方法について簡単にまとめます。
Emotionのインストール
以下のコマンドでモジュールをインストールできます。
npm install --save @emotion/react
スタイルの分離と適用の基本
1. スタイル定義ファイルを作成
まず、スタイル定義を別ファイルに分けます。たとえば、styled.ts
というファイルを作成し、Emotionのcss
関数を使ってスタイルを定義します。
import { css } from "@emotion/react";
export const buttonStyle = css`
background: #fff;
border: 1px solid #999;
padding: 10px 20px;
`;
このファイルには、コンポーネントに適用するための基本的なスタイルが定義されています。このスタイルをReactコンポーネントで使用します。
擬似要素とホバーエフェクトの追加
次に、擬似要素を使ってボタンにアイコンを追加し、ホバー時にそのアイコンの色が変わるスタイルを定義します。
import { css } from "@emotion/react";
export const buttonStyle = css`
background: #fff;
border: 1px solid #999;
padding: 10px 20px;
position: relative;
&::before {
content: "✔";
position: absolute;
left: 10px;
top: 50%;
transform: translateY(-50%);
font-size: 16px;
color: #ffcc00;
transition: color 0.3s ease;
}
&:hover {
background-color: #eee;
&::before {
color: #ff6600;
}
}
`;
この例では、::before
擬似要素を使ってボタンにチェックマークを追加し、ホバー時にその色が変わるように設定しています。
2. コンポーネントでスタイルを適用
次に、スタイルを適用するReactコンポーネントを作成します。ここでは、CustomButton.tsx
というコンポーネントを例に説明します。
import { FunctionComponent } from "react";
import { Symbol } from "../../types/index";
import { buttonStyle } from "./styles";
import { css, ClassNames } from "@emotion/react";
type ButtonProps = {
label: Symbol;
onClickHandler: () => void;
}
export const CustomButton: FunctionComponent<ButtonProps> = ({ label, onClickHandler }: ButtonProps) => {
return (
<ClassNames>
{({ css }) => (
<button className={css(buttonStyle)} onClick={onClickHandler}>
{label}
</button>
)}
</ClassNames>
);
}
ここで、ClassNames
コンポーネントを使用して、スタイルをclassName
プロパティに適用しています。これにより、css
関数を適切に適用でき、外部ファイルからスタイルをインポートして使用することが可能になります。
複数のクラスを組み合わせる
前述の方法では、1つのクラス名を適用する例を示しましたが、複数のクラスを適用したい場合もあります。これを実現するには、ClassNames
コンポーネントを使用し、テンプレートリテラルで複数のクラスを組み合わせることができます。
import { FunctionComponent } from "react";
import { Symbol } from "../../types/index";
import { buttonStyle, hoverStyle } from "./styles";
import { css, ClassNames } from "@emotion/react";
type ButtonProps = {
label: Symbol;
onClickHandler: () => void;
}
export const CustomButton: FunctionComponent<ButtonProps> = ({ label, onClickHandler }: ButtonProps) => {
return (
<ClassNames>
{({ css }) => (
<button className={css`${buttonStyle} ${hoverStyle}`} onClick={onClickHandler}>
{label}
</button>
)}
</ClassNames>
);
}
このように、テンプレートリテラルを使用して、buttonStyle
とhoverStyle
を1つのclassName
プロパティにまとめて適用することができます。これにより、複数のスタイルを組み合わせてボタンに適用できます。
この記述方法はクラスを1つのみ適用したい場合でも使用できます。
3. フォルダ構成
このアプローチを使用する際のフォルダ構成の例は以下の通りです。
project-root/
├── src/
│ ├── components/
│ │ ├── CustomButton.tsx
│ │ └── styled.ts
│ ├── types/
│ │ └── index.ts
│ └── ...
CustomButton.tsx
ファイルで定義したスタイルを、styled.ts
からインポートして使用しています。これにより、コンポーネントのロジックとスタイルが分離され、コードがより管理しやすくなります。
まとめ
Emotionを使用することで、Reactコンポーネントのスタイルを簡単に適用できます。さらに、スタイルを外部ファイルに分離することで、コードの再利用性が高まり、コードベースのメンテナンスが容易になります。また、擬似要素やホバーエフェクトを組み合わせることで、リッチなUIを作成できます。