Getting Started with Chakra UIをやってみた

## はじめに

この記事は、[ミロゴス Advent Calendar 2023](https://qiita.com/advent-calendar/2023/milogos) 7 日目の投稿です。
本記事では、Chakra UI の公式ドキュメントのチュートリアルをやってみたので内容について紹介できればと思います。

> [Getting Started with Chakra UI](https://www.youtube.com/watch?v=wI2vqXsjsIo)
> Chakra UI 公式が出している動画

## Next.js とは

Next.js は、フルスタックの Web アプリケーションを構築するための React フレームワークです。
ユーザーインターフェースを構築するために React コンポーネントを使用し、追加の機能や最適化のために Next.js を利用します。

Next.js は、React に必要なバンドリング、コンパイルなどのツールを抽象化し、自動的に構成します。
これにより、設定に時間を費やすのではなく、アプリケーションの構築に集中することができます。

個々の開発者であっても、または大きなチームの一員であっても、Next.js はインタラクティブで動的で高速な React アプリケーションを構築するのに役立ちます。

> [What is Next.js?](https://nextjs.org/docs#what-is-nextjs)
> Next.js について公式の説明です。

## Chakra UI とは

Chakra UI は、React アプリケーションを構築するためのコンポーネントライブラリです。
Chakra UI は、アプリケーションのデザインやスタイリングを効率的かつ一貫して行うために作られています。

> [Chakra UI](https://chakra-ui.com/)
> Chakra UI の公式サイトです。

## 内容

### 環境構築

#### 新しいプロジェクトの作成

with-typescript テンプレートを使用して、Next.js アプリケーションの新しいプロジェクトを作成します。

```bash
# npx create-next-app [プロジェクト名] [オプション]
npx create-next-app getting-standard --example with-typescript
```

以下のようなディレクトリ構成になっていればOKです。
```
├── README.md
├── components
│   ├── Layout.tsx
│   ├── List.tsx
│   ├── ListDetail.tsx
│   └── ListItem.tsx
├── interfaces
│   └── index.ts
├── next-env.d.ts
├── node_modules
├── package-lock.json
├── package.json
├── pages
│    ├── about.tsx
│    ├── api
│    │   └── users
│    │       └── index.ts
│    ├── index.tsx
│    └── users
│        ├── [id].tsx
│        └── index.tsx
├── tsconfig.json
└── utils
    └── sample-data.ts
```


#### サーバーの起動

Next.js アプリケーションの開発サーバーが起動し、http://localhost:3000 などの URL でアクセスできるようになります。

```bash
yarn dev
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952491/c92e3c3b-eacb-be3e-735a-b6af55b98797.png)

#### Chakra UI のインストール

プロジェクトで Chakra UI を使用するには、ターミナルで次のコマンドを実行します。

```bash
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion
```

#### ChakraProvider の追加

`_app.tsx`ファイルにChakraProviderコンポーネントを追加しています。
これにより、Chakra UI のスタイルやテーマがアプリケーション内で利用可能になります。

##### _app.tsxとは
`app.tsx`は、Appコンポーネントをカスタマイズするためのファイルです。
このファイルは、すべてのページコンポーネントの初期化に利用される特別なコンポーネントです。
具体的には、各ページで共通の処理や設定を統一的に扱うために使用されます。
つまり、これを使用することで、全体のアプリケーションにわたって一貫性のある動作や外観を実現することができます。

- pages配下に`_app.tsx`を作成
```tsx:_app.tsx
import { ChakraProvider } from "@chakra-ui/react";
import type { AppProps } from "next/app";

export default function App({ Component, pageProps }: AppProps) {
  return (
    <ChakraProvider>
      <Component {...pageProps} />
    </ChakraProvider>
  );
}
```

以下のような画像になれば、UI が正常に初期化されたことを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952491/6d7cae2d-e398-aceb-f5a6-cd4c0e209f86.png)

以上で Next.js + Chakra UI の環境構築が完了です。

### 画面の作成

チュートリアルに沿って、ログイン画面を作成します。

#### ログイン画面の作成
ログイン画面の作成には、Chakra UI のコンポーネントが使用されています。
ログインフォームには、メールアドレスとパスワードの入力フィールド、そしてログインボタンが含まれています。

##### 必要なコンポーネントのインポート

```tsx
import { Button, Flex, Heading, Input } from "@chakra-ui/react";
```

各コンポーネントを Chakra UI からインポートしています。

##### Flexコンポーネントの使用

```tsx
<Flex height="100vh" alignItems="center" justifyContent="center">
  <Flex direction="column" background="gray.100" padding={12} rounded={6}>
    ...
  </Flex>
</Flex>
```

Flex コンポーネントは、柔軟でレスポンシブなフレックスボックスのレイアウトを提供します。

- height="100vh"

  - height プロパティは、"100vh" と設定されています。これにより、親要素いっぱいに画面を占める高さが指定されます。vh はビューポートの高さに対する相対的な単位であり、画面の高さに合わせて柔軟に調整されます。

- alignItems="center"

  - alignItems プロパティは、子要素（この場合はログインフォーム）を垂直方向に中央揃えに設定しています。これにより、画面の中央にログインフォームが配置されます。

- justifyContent="center"

  - justifyContent プロパティは、子要素を水平方向に中央揃えに設定しています。これにより、ログインフォームが水平方向にも画面の中央に配置されます。

- direction="column":

  - direction プロパティは、子要素の配置方向を指定します。この場合、"column" に設定されているため、子要素は縦方向に配置されます。つまり、要素が縦に積まれるようになります。

- background="gray.100"

  - background プロパティは、背景色を指定します。"gray.100" は、Chakra UI のカラーパレットで定義された灰色の中で明るいバリエーションです。この場合、グレーの背景色が指定されています。

- padding={12}

  - padding プロパティは、要素の内部の余白を指定します。12 はピクセル単位の余白の大きさです。内部の要素が余白から離れて配置されることになります。

- rounded={6}
  - rounded プロパティは、要素の角を丸くする効果を指定します。6 は角の丸みの程度を示しています。この場合、rounded={6} により、要素の角がやや丸くなります。

> [Flex コンポーネント](https://chakra-ui.com/docs/components/flex)
> Flex は、display が flex に設定された Box であり、便利なスタイルの省略形が付いています。これは div 要素をレンダリングします。

##### Headingコンポーネントの使用

```tsx
<Heading mb={6}>Log in</Heading>
```

Heading コンポーネントを使用して、ログインフォームのタイトルを表示しています。

- mb={6}
  - mb プロパティは、マージンボトムを指定しています。この場合、6 の値が指定されており、タイトルの下に相対的に大きなマージンが設定されます。これにより、タイトルと後続の要素との間にスペースができます。

> [Heading コンポーネント](https://chakra-ui.com/docs/components/heading)
> Heading は、セマンティックな HTML 見出し要素をレンダリングするために使用されます。

##### Inputコンポーネントの使用

```tsx
<Input placeholder='xxx@chakra-ui.com' variant="filled" mb={3} type="email" />
<Input placeholder='*******' variant="filled" type="password" />
```

Input コンポーネントを使用して、メールアドレスとパスワードの入力フィールドを作成しています。

- placeholder

  - placeholder プロパティは、ユーザーが入力する際に表示されるプレースホルダーテキストを指定します。例えば、メールアドレスの入力フィールドには "xxx@chakra-ui.com" が表示されます。

- variant="filled"

  - variant プロパティは、"filled" と設定されています。これにより、入力フィールドに背景色を持たせるスタイルが適用されます。

- mb={3}

  - mb プロパティは、マージンボトムを指定しています。この場合、3 の値が指定されており、メールアドレスの入力フィールドの下に小さなマージンが設定されます。

- type="email"、type="password"
  - type プロパティは、入力フィールドの種類を指定します。"email" と "password" に設定されており、それぞれメールアドレス入力用とパスワード入力用のフィールドを表示します。

> [Input コンポーネント](https://chakra-ui.com/docs/components/input)
> Input コンポーネントは、テキストフィールドでユーザーの入力を受け取るために使用されるコンポーネントです。

##### Buttonコンポーネントの使用

```tsx
<Button colorScheme="teal" mt={4}>
  Log in
</Button>
```

Button コンポーネントを使用して、ログインボタンを作成しています。

- colorScheme="teal"
  - colorScheme プロパティは、ボタンの色を指定します。この場合、"teal" に設定されており、ティール色のボタンが表示されます。
- mt={4}
  - mt プロパティは、マージントップを指定しています。4 の値が指定されており、ボタンの上に相対的に大きなマージンが設定されます。これにより、ボタンと前の要素との間にスペースができます。

> [Button コンポーネント](https://chakra-ui.com/docs/components/button)
> Button コンポーネントは、フォームの送信、ダイアログの表示、アクションのキャンセル、削除操作の実行など、アクションやイベントをトリガーするために使用されます。

##### 全体のコード

- pages/index.tsx

```tsx
import { Button, Flex, Heading, Input } from "@chakra-ui/react";

const IndexPage = () => (
  <Flex height="100vh" alignItems="center" justifyContent="center">
    <Flex direction="column" background="gray.100" padding={12} rounded={6}>
      <Heading mb={6}>Log in</Heading>
      <Input
        placeholder="xxx@chakra-ui.com"
        variant="filled"
        mb={3}
        type="email"
      />
      <Input placeholder="*******" variant="filled" type="password" />
      <Button colorScheme="teal">Log in</Button>
    </Flex>
  </Flex>
);

export default IndexPage;
```

コードの結果、以下の画面デザインが作成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952491/2782e440-fdb1-ab75-83d2-392df390fd5c.png)

#### ダークモード機能の追加

Chakra UI の useColorMode フックを使用して、カラーモード（ダークモードやライトモードなど）をトグルするための関数 toggleColorMode を使用します。

toggleColorMode を呼び出すことで、アプリケーションのカラーモードを切り替えることができます。
一般的には、ユーザーがトグルボタンをクリックしたり、設定画面から選択したりする際に使用されます。

##### useColorMode フックのインポート

```tsx
import { useColorMode } from "@chakra-ui/react";
```

useColorMode フックを Chakra UI からインポートしています。

##### useColorMode フックの使用

```tsx
const { toggleColorMode } = useColorMode();

<Button onClick={toggleColorMode}>Toggle Color Mode</Button>;
```

useColorMode フックを使って、toggleColorMode 関数を取得しています。これにより、ボタンがクリックされたときにカラーモードをトグルすることができます。

##### useColorModeValue フックのインポート

```tsx
import { useColorModeValue } from "@chakra-ui/react";
```

useColorModeValue フックを Chakra UI からインポートしています。

##### useColorModeValue フックの使用

```tsx
const formBackground = useColorModeValue("gray.100", "gray.700");
<Button onClick={toggleColorMode}>Toggle Color Mode</Button>;
```

useColorModeValue フックを使用して、フォームの背景色をライトモードとダークモードを取得しています。

- onClick={toggleColorMode}

  - onClick プロパティは、ボタンがクリックされたときに実行される関数を指定します。この例では、toggleColorMode という関数が指定されています。

##### 全体のコード

```tsx
import {
  Button,
  Flex,
  Heading,
  Input,
  useColorMode,
  useColorModeValue,
} from "@chakra-ui/react";

const IndexPage = () => {
  const { toggleColorMode } = useColorMode();
  const formBackground = useColorModeValue("gray.100", "gray.700");

  return (
    <Flex height="100vh" alignItems="center" justifyContent="center">
      <Flex
        direction="column"
        background={formBackground}
        padding={12}
        rounded={6}
      >
        <Heading mb={6}>Log in</Heading>
        <Input
          placeholder="xxx@chakra-ui.com"
          variant="filled"
          mb={3}
          type="email"
        />
        <Input placeholder="*******" variant="filled" type="password" />
        <Button mb={6} colorScheme="teal">
          Log in
        </Button>
        <Button onClick={toggleColorMode}>Toggle Color Mode</Button>
      </Flex>
    </Flex>
  );
};

export default IndexPage;
```

コードの結果、以下の画面デザインが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952491/fa5f36c3-6a97-679a-7c5e-2d957aa46fe4.png)

Toggle Color Modeボタン押下後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952491/13c0da63-ea75-ae4e-61e9-7d74afbee985.png)

## さいごに
このチュートリアルを試してみた感想として、とても満足しています。
Next.jsとChakra-UIの環境構築がスムーズで、迅速に開発を始めることができました。
また、Chakra-UIを使用して簡単なレイアウトを作成できたことがとても楽しかったです。
UIライブラリを検討している方には、ぜひこのチュートリアルを試してみていただければと思います。