Tailwind CSS×カスタムカラーパレット：ハードコードしないテクニック

## 1. はじめに：Tailwindでのカラーパレット管理

Tailwind CSSは、効率的にUIを構築するための強力なツールです。  
多くのプロジェクトでは、`tailwind.config.ts` で独自のカラーパレットを定義し、デザインの一貫性を保っています。  
例えば、以下のように定義すれば、プロジェクト全体で使えるカラーパレットが実現できます。

```ts
// tailwind.config.ts の一例
import type { Config } from 'tailwindcss'
import scrollbarHide from 'tailwind-scrollbar-hide'

const config: Config = {
  content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
  theme: {
    extend: {
      colors: {
        ap: {
          gray: {
            DEFAULT: '#9f9f9f',
            0: '#fff',
            50: '#fafafa',
            100: '#f5f5f5',
            200: '#efefef',
            300: '#e1e1e1',
            400: '#bebebe',
            500: '#9f9f9f',
            600: '#767676',
            700: '#626262',
            800: '#434343',
            900: '#222',
            1000: '#000',
          },
        },
      },
    },
  },
}
export default config
```

クラス名に `bg-ap-gray-300` や `border-ap-gray` と指定するだけで、手軽に使えるのはとても魅力的です。  
### 使用例

👆のように定義されているとき、classNameに次のように指定することでカラーを使用することができます。
![Tailwindカラーパレットの表示例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006880/40f60d23-3c77-4760-bbfb-133259005a5f.png)
```tsx
// ap-grayなど数値suffixがない場合はDEFAULTが当てられます
  <div className="bg-ap-gray-300 border border-lg border-ap-gray">
    <span className="text-ap-gray-1000 p-4">
      hogehoge
    </span>
  </div>
```


---

## 2. 問題：SVGやfill・strokeでの苦労

しかし、ここで一つのジレンマが発生します。  
ボタンや背景以外に、SVGの `fill` や `stroke`、もしくはJavaScript内で直接カラーコードを指定しなければならない場面では、  
毎回 `#9f9f9f` のようなカラーコードを手入力する必要があり、保守性が低下してしまいます。  

- **問題点:**  
  - 定義済みのカラーパレットが活かしきれない  
  - カラーコードの重複記述で、変更時に手間がかかる

---

## 3. 解決策：Tailwindの設定からカラーコードを動的に取得する

ここで登場するのが、Tailwindのカラーパレット設定をそのまま利用してカラーコードを返すユーティリティ関数です。  
この仕組みを導入すれば、SVGやその他のコンポーネントでも、わざわざカラーコードをハードコーディングする必要がなくなります。

### 実装例：`utils/tailwindColor.ts`

```ts
import resolveConfig from 'tailwindcss/resolveConfig'
import tailwindConfig from '../../tailwind.config'

const fullConfig = resolveConfig(tailwindConfig)

export const getTailwindColor = (colorPath: string) => {
  // 'ap-gray-600' や 'ap-gray-DEFAULT' の形式で指定
  const colors = fullConfig.theme.colors
  return colorPath.split('-').reduce((acc: any, key) => acc[key], colors)
}
```

この関数は、`tailwind.config.ts` に定義されたカラーパレットを元に、  
指定したパス文字列（例: `'ap-gray-600'`）を辿ってカラーコード（例: `#767676`）を返してくれます。

### 利用例

```ts
const color = getTailwindColor('ap-gray-600') // → #767676 を返す
const color2 = getTailwindColor('ap-gray-DEFAULT') // → #9f9f9f を返す
```

また、以下のようにSVGコンポーネント内で活用することで、Tailwindで設定したカラーを容易に反映できます。(Reactのコンポーネントを例にとっています）

`share-icon.tsx`
```tsx
import { getTailwindColor } from 'utils/tailwindColor'

type IconProps = {
  fill?: string
  className?: string
}

const ShareIcon = ({ fill = 'ap-black-300', className = '' }: IconProps) => {
  const fillColor = getTailwindColor(fill)
  return (
    <svg
      width="25"
      height="25"
      viewBox="0 0 25 25"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
      className={className}
    >
      <g clipPath="url(#clip0_400_3071)">
        <path
          d="M16.5 5.5L15.08 6.92L13.49 5.33V16.5H11.51V5.33L9.92 6.92L8.5 5.5L12.5 1.5L16.5 5.5ZM20.5 10.5V21.5C20.5 22.6 19.6 23.5 18.5 23.5H6.5C5.39 23.5 4.5 22.6 4.5 21.5V10.5C4.5 9.39 5.39 8.5 6.5 8.5H9.5V10.5H6.5V21.5H18.5V10.5H15.5V8.5H18.5C19.6 8.5 20.5 9.39 20.5 10.5Z"
          fill={fillColor}
        />
      </g>
      <defs>
        <clipPath id="clip0_400_3071">
          <rect
            width="24"
            height="24"
            fill="white"
            transform="translate(0.5 0.5)"
          />
        </clipPath>
      </defs>
    </svg>
  )
}

export default ShareIcon
```
次のようにアイコンにfillを渡すだけで、色分けできるようになりました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006880/96b480f1-0e0b-4bc3-a9fb-2e6200628b35.png)
```tsx
    <ShareIcon />
    <ShareIcon fill='ap-red-700' />
    <ShareIcon fill='ap-blue-700' />
```



---

## 4. なぜこのアプローチが有効なのか

- **一元管理:**  
  Tailwindの設定に沿ったカラーパレットを、そのまま各コンポーネントで再利用できるため、メンテナンスが楽になります。

- **変更が容易:**  
  カラーの変更が必要な場合、`tailwind.config.ts` のみ修正すれば全体に反映されるため、開発スピードと正確性が向上します。

- **再利用性:**  
  コンポーネント毎に異なるカラーコードを記述する必要がなく、コードの再利用性が向上します。

---

## 5. まとめ

Tailwind CSSでカラーパレットを一元管理しつつ、SVGやその他の場面で同一のカラーを使い回すためのこのテクニックは、コードの効率化とコードの保守性向上に貢献します。  
この仕組みを採用することで、デザインの一貫性を保ちながら開発できるとおもいます。

ぜひ、感想や改善案をコメントで教えてください！  
ストックついでに いいねもいただけますと幸いです！