Next.js13でNextUIのテーマとtailwindcssのテーマをカスタマイズしたい

# NextUIのテーマをカスタマイズしたい
## 概要
- ライトモード、ダークモードを設定し、それぞれのprimary、secondary等の設定、さらに独自のテーマを追加したい。

## 環境
- Next.js 13
- Node v20.5.0
- NextUI v2
- tailwindcss

## ディレクトリ構成
client/src/app

## 手順
## darkモード lightモードの設定
### ライブラリインストール
```npm i next-themes```

### appディレクトリ配下にproviders.tsx作成

### ThemeProviderでPageをラップ
```tsx::providers.tsx
'use client';

import { NextUIProvider } from '@nextui-org/react';
import { ThemeProvider as NextThemesProvider } from 'next-themes';

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <NextUIProvider>
       <NextThemesProvider attribute='class' defaultTheme='light'>
         {children}
       </NextThemesProvider>
    </NextUIProvider>
  );
}
```

### appディレクトリ配下にcomponentsディレクトリを作成

### componentsディレクトリ配下にThemeSwitcher.tsxを作成し切り替えするスイッチャーを作成
```tsx:ThemeSwitcher.tsx
'use client';

import { useTheme } from 'next-themes';
import { Switch } from '@nextui-org/switch';
import { SunIcon } from '@heroicons/react/24/solid';
import { MoonIcon } from '@heroicons/react/24/outline';

export const ThemeSwitcher = () => {
  const { theme, setTheme } = useTheme();

  return (
    <div className='flex justify-end mb-3'>
      <Switch
        defaultSelected
        size='lg'
        color='primary'
        startContent={<SunIcon />}
        endContent={<MoonIcon />}
        onValueChange={(isSelected) => setTheme(isSelected ? 'light' : 'dark')}
      />
    </div>
  );
};
```

### 後はコンポーネントを呼ぶだけで切り替えは可能に
- 切り替えするとローカルストレージにdark、lightが保存される

## テーマの編集
- テーマは```tailwindconfig.ts```ファイルで管理している。

### tailwindconfig.tsの編集
```ts:tailwindconfig.ts

import type { Config } from "tailwindcss";
import { nextui } from "@nextui-org/react";

const config: Config = {
    content: ["./src/pages/**/*.{js,ts,jsx,tsx,mdx}", "./src/components/**/*.{js,ts,jsx,tsx,mdx}", "./src/app/**/*.{js,ts,jsx,tsx,mdx}", "./node_modules/@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}"],
    theme: {
        extend: {
            // tailwind側のカラー定義カスタマイズ
            colors: {
                darkgray: "#f97316",
            },
            backgroundImage: {
                "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
                "gradient-conic": "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
            },
        },
    },
    darkMode: "class",
    plugins: [
        nextui({
            themes: {
                light: {
                    // NextUI側のカラー定義カスタマイズ
                    colors: {
                        default: {
                            DEFAULT: "#ffffff",
                            foreground: "#ffffff",
                        },
                        primary: {
                            DEFAULT: "#EFAA52",
                            foreground: "#ffffff",
                        },
                        secondary: {
                            DEFAULT: "#E7CC8F",
                            foreground: "#ffffff",
                        },
                        success: {
                            DEFAULT: "#008000",
                            foreground: "#ffffff",
                        },
                        warning: {
                            DEFAULT: "#F8F3E6",
                            foreground: "#ffffff",
                        },
                        danger: {
                            DEFAULT: "#b22222",
                            foreground: "#ffffff",
                        },
                        tertiary: {
                            DEFAULT: "#b22222",
                            foreground: "#ffffff",
                        },
                    },
                },
                dark: {
                    colors: {
                        default: {
                            DEFAULT: "#000000",
                            foreground: "#282828",
                        },
                        primary: {
                            DEFAULT: "#6C4F70",
                            foreground: "#282828",
                        },
                        secondary: {
                            DEFAULT: "#757081",
                            foreground: "#282828",
                        },
                        success: {
                            DEFAULT: "#193446",
                            foreground: "#282828",
                        },
                        warning: {
                            DEFAULT: "#ffffff",
                            foreground: "#282828",
                        },
                        danger: {
                            DEFAULT: "#AB3E16",
                            foreground: "#282828",
                        },
                        tertiary: {
                            DEFAULT: "#101010",
                            foreground: "#ffffff",
                        },
                    },
                },
            },
        }),
    ],
};
export default config;

```

- テーマはデフォルトでdefault,primary,secondary,success,warning,dangerが用意されている
- 使用するときは```className="bg-primary text-warning border-secondary"```のようにして使えるが、```bg-primary-500```の用にはできない。

## 独自テーマのカスタマイズ
### tertiaryの追加
- 独自でtertiaryのような項目を追加するとtypescriptエラーになるので、```node_modules/@nextui-org/theme/dist/colors/types.d.ts```の修正が必要
```ts:types.d.ts
type ThemeColors = BaseColors & {
    default: ColorScale;
    primary: ColorScale;
    secondary: ColorScale;
    success: ColorScale;
    warning: ColorScale;
    danger: ColorScale;
    tertiary: ColorScale;
};
```
- 型定義を追加するだけ．．．と言いたいが、ライブラリの修正になるので、パッチをあてて更新する必要がある
https://qiita.com/yowayowa_engineer/items/30c6439339b31964133e

## tailwindcss側のテーマの設定
- 同じくtailwindconfig.tsの上の方にthemeがあるのでそこにcolorを追加するだけ。
```ts:tailwindconfig.ts
theme: {
        extend: {
            // tailwind側のカラー定義カスタマイズ
            colors: {
                orange: "#f97316",
            },
            backgroundImage: {
                "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
                "gradient-conic": "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
            },
        },
    },
```