他のサイトと差をつけるUIを、簡単に ～NextUIを添えて

## はじめに
突然ですが、ReactのUIライブラリといえば何を思い浮かべますか？
ここで、大半の人は「MUI(MaterialUI)」を思い浮かべると思います。または、「ChakraUI」を思い浮かべる人もいるかもしれません。
しかし、これらのUIライブラリには決定的な弱点が存在します。それは、、、
**見た目がありがちなものになってしまう**
ということ。実際、MUIをそのまま使ってしまうと、いろんなサイトでよく見るUIになってしまいます。
そこで今回は、あまり使われていない、かつカスタマイズも簡単なUIライブラリを紹介します！

## NextUIとは？
https://nextui.org/
NextUIとは、Next.jsでおなじみのVercelが提供するUIライブラリです。コンポーネントの種類も(MUIほどではありませんが)多く、見た目もかなりイケてるものになります。
さらに、TailwindCSSとの相性が非常によく、TailwindCSSを使用して自分好みにカスタマイズすることが可能です。
正直他のサイトと差別化するのであれば、個人的にはこれ一択だと思います。

## 使用方法
使用方法は、以下のページを見るのが簡単ですが、私はうまくいかないことがあるので実際にやってみたコードを紹介します。
https://nextui.org/docs/guide/installation

なお、ここから先で紹介するインストール手順は、以下の環境で使用する場合のみ使用可能となります。
- Next.js (v14) App Router

他の場合(Viteを使用している場合など)は、公式手順通りにインストールすることをおすすめします。

### １．インストール
以下のコマンドを実行して、NextUIとFramorMotionをインストールします。
```
npm i @nextui-org/react framer-motion
```

### ２．tailwind.config.js を編集
tailwind.config.jsを以下のように編集します。
```ts:tailwind.config.ts

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

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: {
      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()],
};
export default config;

```

### ３．providers.tsx を作成・編集
src/app/providers.tsx を作成します。
ファイルの内容は以下の通りです。
```tsx:providers.tsx
'use client'

import {NextUIProvider} from '@nextui-org/react'

export function Providers({children}: { children: React.ReactNode }) {
  return (
    <NextUIProvider>
      {children}
    </NextUIProvider>
  )
}
```

### ４．layout.tsxにprovidersを追加
src/app/layout.tsx が無い場合には作成します。以下の通りに編集します。
```tsx: layout.tsx

import type { Metadata } from "next";
import "./globals.css";
import { Providers } from "./providers";

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="ja">
      <body>
        <Providers>
          {children}
        </Providers>
      </body>
    </html>
  );
}

```

### ５．完了・動作確認
以上で導入は完了です。最後に動作確認を行いましょう。
モーダルが正常に動けば他コンポーネントはおそらく正常に動作すると思います。
page.tsxを以下の内容に変更し、動作を確認してみましょう！

```tsx: page.tsx

'use client'
import { Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, useDisclosure } from "@nextui-org/react";

export default function Home() {
  const {isOpen, onOpen, onOpenChange} = useDisclosure();
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <Button onPress={onOpen}>Open Modal</Button>
      <Modal isOpen={isOpen} onOpenChange={onOpenChange}>
        <ModalContent>
          {(onClose) => (
            <>
              <ModalHeader className="flex flex-col gap-1">Modal Title</ModalHeader>
              <ModalBody>
                <p> 
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                  Nullam pulvinar risus non risus hendrerit venenatis.
                  Pellentesque sit amet hendrerit risus, sed porttitor quam.
                </p>
                <p>
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                  Nullam pulvinar risus non risus hendrerit venenatis.
                  Pellentesque sit amet hendrerit risus, sed porttitor quam.
                </p>
                <p>
                  Magna exercitation reprehenderit magna aute tempor cupidatat consequat elit
                  dolor adipisicing. Mollit dolor eiusmod sunt ex incididunt cillum quis. 
                  Velit duis sit officia eiusmod Lorem aliqua enim laboris do dolor eiusmod. 
                  Et mollit incididunt nisi consectetur esse laborum eiusmod pariatur 
                  proident Lorem eiusmod et. Culpa deserunt nostrud ad veniam.
                </p>
              </ModalBody>
              <ModalFooter>
                <Button color="danger" variant="light" onPress={onClose}>
                  Close
                </Button>
                <Button color="primary" onPress={onClose}>
                  Action
                </Button>
              </ModalFooter>
            </>
          )}
        </ModalContent>
      </Modal>
    </main>
  );
}

```

## NextImageを使用する
NextUIで、Next.jsにあるNextImageを使用するには以下のようにします。
```tsx
import React from "react";
import {Image} from "@nextui-org/react";
import NextImage from "next/image";

export default function App() {
  return (
    <Image
      as={NextImage}
      width={300}
      height={200}
      src="https://nextui-docs-v2.vercel.app/images/hero-card-complete.jpeg"
      alt="NextUI hero Image"
    />
  );
}

```

## 最後に
NextUIはまだあまり使われていないですが、かなり使い勝手の良いUIライブラリだと思います。他サイトに極度に似通ることを防げて、Tailwindcssでのスタイルのカスタマイズもしやすいです。2024年に一番おすすめできるUIライブラリです！