Chakra UI V3の紹介

これは[SMat Advent Calendar 2024](https://qiita.com/advent-calendar/2024/s-mat) の12/3分の記事です。
こんにちは、株式会社エスマットにてフロントエンドを開発をしています、川上と申します

2024年10月にリリースされた**Chakra UI V3**は、パフォーマンス向上や新しいコンポーネントの追加など、多くの魅力的な機能を備えています。本記事では、Chakra UI V3の導入方法から新機能の紹介、パフォーマンスの向上について紹介します。

Chakra UIは、Reactアプリケーションの開発において非常に人気のあるUIライブラリであり、シンプルで直感的なAPIと豊富なコンポーネントを提供しています。今回のバージョンアップでは、完全なリライトによりパフォーマンスが大幅に向上し、**25以上の新しいコンポーネント**が追加されました。

## 導入とセットアップ
Chakra UI V3のセットアップ方法は公式ドキュメントでプラットフォームに応じた方法を書かれているので参考にしてください。ここではマニュアルで設定する方法を記載します。

### Chakra UIのインストール
Chakra UIとその依存関係をインストールします。Chakra UIは@emotion/reactに依存しているため、こちらも一緒にインストールします。

```shell
npm i @chakra-ui/react @emotion/react
```

### スニペットの導入
スニペットは、コンポーネントを組み合わせて独自の共通コンポーネントを作成する場合などに役立ちます。例えば、チェックボックスやラジオボタンなどの複合コンポーネントは、多くのプロパティやスタイルを持つことが多く、これを一から設定するのは手間がかかります。スニペットを使うことで、基本的な設定を自動化し、必要な部分だけをカスタマイズすることができます。

スニペットの導入するには、スニペットCLIを実行してプロジェクトにスニペットを追加します。

```shell
npx @chakra-ui/cli snippet add
```

このコマンドを実行すると、プロジェクトのcomponents/uiディレクトリにプリミティブなコンポーネントが追加されます。例えば、チェックボックスのスニペットは以下となっています。

```components/ui/checkbox.tsx
import { Checkbox as ChakraCheckbox } from "@chakra-ui/react"
import * as React from "react"

export interface CheckboxProps extends ChakraCheckbox.RootProps {
  icon?: React.ReactNode
  inputProps?: React.InputHTMLAttributes<HTMLInputElement>
  rootRef?: React.Ref<HTMLLabelElement>
}

export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
  function Checkbox(props, ref) {
    const { icon, children, inputProps, rootRef, ...rest } = props
    return (
      <ChakraCheckbox.Root ref={rootRef} {...rest}>
        <ChakraCheckbox.HiddenInput ref={ref} {...inputProps} />
        <ChakraCheckbox.Control>
          {icon || <ChakraCheckbox.Indicator />}
        </ChakraCheckbox.Control>
        {children != null && (
          <ChakraCheckbox.Label>{children}</ChakraCheckbox.Label>
        )}
      </ChakraCheckbox.Root>
    )
  },
)
```

このスニペットをカスタマイズして、独自の共通コンポーネントを作成します。完成したら以下のように、アプリケーションでこのコンポーネントを使用できます。

```src/App.tsx
import { Box, Button } from "@chakra-ui/react";
import { Checkbox } from "@/components/ui/checkbox";

function App() {
  return (
    <Box p={4}>
      <Button colorScheme="teal">Click me</Button>
      <Checkbox>Click me</Checkbox>
    </Box>
  );
}

export default App;
```

### ChakraProviderの設定
Chakra UIを使用するためには、アプリケーション全体にProviderコンポーネントを設定する必要があります。これにより、Chakraのテーマやスタイルをアプリケーション全体で使用できるようになります。

スニペットで追加された`components/ui/provider`ディレクトリに`Provider`コンポーネントが生成されているので。このコンポーネントを使用してアプリケーションをラップします

```tsx
import { Provider } from "@/components/ui/provider"

function App({ Component, pageProps }) {
  return (
    <Provider>
      <Component {...pageProps} />
    </Provider>
  )
}
```

これで、Chakra UIのスタイリングシステムとカラーモードがアプリケーション全体で使用できるようになります。

### 基本的なコンポーネントの使用
Chakra UIが正しく設定されたので、基本的なコンポーネントを使用してみましょう。以下のコードをsrc/App.jsファイルに追加して、ButtonとBoxコンポーネントを使った簡単なUIを作成します。

```src/App.js
import { Box, Button } from "@chakra-ui/react";

function App() {
  return (
    <Box p={4}>
      <Button colorScheme="teal">Click me</Button>
    </Box>
  );
}

export default App;
```
これで、Chakra UIの基本的なセットアップが完了しました。ブラウザでアプリケーションを開くと、Chakra UIのスタイルが適用されたボタンが表示されるはずです。


## Semantic Tokensの紹介
Chakra UI V3では、セマンティックトークン（Semantic Tokens）を導入することで、スタイリングの柔軟性と効率性が大幅に向上しました。セマンティックトークンを使用すると、各コンポーネントを手動で再スタイリングすることなく、トークンを簡単にパーソナライズできます。

### セマンティックトークンとは？
セマンティックトークンは、各カラーパレットに対して7つの異なるトークンを提供します。これにより、ダークモードを考慮することなく、柔軟にカスタマイズが可能です。以下がChakra UI V3で提供されるセマンティックトークンです：

**solid:** パレットのソリッドカラー
**muted:** パレットのミュートバージョン
**subtle:** パレットのサブトルバージョン（ミュートよりも低い）
**emphasized:** パレットの強調バージョン
**contrast:** ソリッド背景上に使用するカラー（「on-solid」とも呼ばれる）
**fg:** パレットの前景色
**focusRing:** パレットのフォーカスリングカラー

### セマンティックトークンの使用例
以下は、赤色のセマンティックトークンを使用して、ダークモードに自動的に適応する例です。

```tsx
// A subtle version of red
<Box bg="red.subtle" color="red.fg">
  Welcome
</Box>

// A solid version of red
<Box bg="red.solid" color="red.contrast">
  Welcome
</Box>
```
この例では、red.subtleとred.solidを使用して背景色を設定し、red.fgとred.contrastを使用して前景色を設定しています。これにより、ダークモードとライトモードの両方で適切にスタイルが適用されます。

### colorPalette機能を活用する
Chakra UI V3では、新しいcolorPalette機能を活用することで、CSS変数を使用してDOMツリーの任意の深さで色を簡単に切り替えることができます。

```tsx
<Box colorPalette="red">
  <Box bg="colorPalette.subtle" color="colorPalette.fg">
    Welcome
  </Box>
  <Box bg="colorPalette.solid" color="colorPalette.contrast">
    Welcome
  </Box>
</Box>
```
この例では、colorPaletteを使用して、赤色のパレットを簡単に適用しています。これにより、色のプレースホルダーを作成し、DOMツリーの任意の深さで色を変更することができます。

## パフォーマンス向上について
Chakra UI V3は、パフォーマンスの向上に重点を置いて開発されました。これにより、ユーザーエクスペリエンスが向上し、開発者にとっても効率的な開発環境が提供されます。

### テーマ内のランタイム関数の削除
以前のバージョンでは、テーマシステム内で関数を使用することが許可されていましたが、これがランタイムパフォーマンスに悪影響を与える可能性がありました。Chakra UI V3では、この問題を解決するために「レシピ（recipes）」と呼ばれるバリアントベースのシステムに切り替えました。

#### レシピ（recipes）とは？
レシピは、テーマ内でのスタイルのバリエーションを簡単に定義するためのシステムです。これにより、ランタイムでのスタイル解決が高速化され、パフォーマンスが向上します。

### スタイリングエンジンの外部化
Chakra UI V3では、スタイリングエンジンをReactツリーの外部で初期化するように変更しました。これにより、各コンポーネントがスタイリングエンジンを消費する形となり、スタイルの解決とレンダリング時間が大幅に短縮されます。

### CSSアニメーションへの移行
Chakra UI V3では、アニメーションライブラリとして使用していたframer-motionの依存を削除し、プラットフォームのネイティブなアニメーション機能を使用するように変更しました。これにより、パフォーマンスが向上し、アプリケーションのバンドルサイズも削減されます。



### 感想
2024年10月にリリースされたChakra UI V3は、パフォーマンス向上や新しいコンポーネントの追加など、多くの魅力的な機能を備えており、実際に触ってみてその進化を実感しました。
弊社も現在はChakra UI V2を利用しているので、V3への移行を検討する価値が十分にあると感じました。特に、パフォーマンスの向上と新しいコンポーネントの追加は、プロジェクトの効率化と品質向上に直結するため、今後のアップデート計画に組み込む予定です。
また、Chakra UI V3の新機能や改善点を活用することで、より洗練されたユーザーインターフェースを提供できると確信しています。今後もChakra UIの進化を注視しつつ、最新の技術を積極的に取り入れていきたいと思います。