水戸地図(β)

2024年02月21日

Park UI + Panda CSSでReact Server Components(RSC)に対応

ヘッドレスコンポーネントライブラリArk UIのコンポーネントをゼロランタイムCSS in JSでスタイリングしたUIコンポーネントライブラリPark UIを使ってNext.jsのApp Routerに対応する記事です。

Park UI
park-ui.com
デモページ
nextjs-park-ui-on-vercel.vercel.app

動機

Next.js v13で導入された App Router では React Server Components(RSC) の理解が必須となります。しかしながら Material-UI Chakra UI など従来のReactコンポーネントライブラリのスタイルシステムは Emotion ベースであることが多く、2024年2月現在でRSCへの対応が不十分であり、新たにApp Routerを学びたい場合にUIデザインは障壁となります。

Park UIとは

Ark UIのコンポーネントをゼロランタイムCSS in JSでスタイリングしたUIコンポーネントライブラリです。通常UIコンポーネントライブラリはReactやVueなど特定のフレームワークにのみ対応していますが、Park UIはReact, Vue, Solidで使うことができます。というのも、Park UIはドキュメントからコンポーネントのコードをコピー&ペーストして使用するからです。

Park UIの特徴としてスタイルシステムは Tailwind CSS Panda CSS のどちらか好きな方を選択することができます。

Ark UIとは

Ark UI Chakra UI の開発チームによるヘッドレスコンポーネントライブラリです。ヘッドレスコンポーネントライブラリとはスタイルを持たないコンポーネントライブラリのことで、コンポーネントからスタイルを排除しアクセサビリティの実装やインタラクティブな機能面を抜き出すことで、ユーザーが柔軟にカスタマイズすることができます。

Ark UI
ark-ui.com

Panda CSSとは

Chakra UIの開発チームによるゼロランタイムCSS in JSライブラリです。Tailwind CSSに大きな影響を受けていますが、Tailwind CSSと決定的に異なる点は、独自のクラス名を覚える必要はなく、従来のCSS in JSのようにオブジェクトとして堅安全性を保ちながらスタイルを記述できる点です。

Panda CSS
panda-css.com

各ライブラリの関係性

  • Chakra UI : Reactコンポーネントライブラリ
  • Zag : Chakra UIが開発するロジック・ステート制御のライブラリ
  • Ark UI : Chakra UIが開発するZagをベースとしたヘッドレスコンポーネントライブラリ
  • Panda CSS : Chakra UIが開発するゼロランタイムCSS in JSライブラリ
  • Park UI : Ark UIをPanda CSSまたはTailwind CSSでスタイリングしたコンポーネントライブラリ(Chakra UI開発チーム所属の個人によるサードパーティ)

将来的にはChakra UI v3がZag, Ark UI, Panda CSSで構成される予定です。Park UIは現時点でPanda CSSを使ってRSCに対応する有効な手段であると同時に、Chakra UI v3の導入の準備にもなります。
将来的にChakra UIはZag, Ark UI, Panda CSSで構成される予定です。ただし開発中のChakra UI v3は引き続きEmotionをベースとすることが明言されています。
2024/03/29追記 やはりChakra UI v3はZag, Ark UI, Panda CSSで構成されるようです。

The future of Chakra UI
www.adebayosegun.com

どのような場合に向いているか

  • Next.jsのApp Router、React Server Components(RSC)に対応したい
  • ゼロランタイムCSS in JSを使いたい
  • でも基礎的なコンポーネントを一から設計するのは面倒
  • Tailwind CSSの記法が苦手 (Panda CSSを使いたい)

自分はTailwind CSSの記法が苦手なのでPanda CSSが使えるライブラリを探した結果Park UIに行き着きましたが、Tailwindに馴染みがある方であればPark UIに影響を与えたライブラリに shadcn/ui があり、こちらの方が日本語の情報も多いと思われます。

広告

環境

ここではNext.js(App Router) + Panda CSSの環境を前提としています。

- @ark-ui/react: ^2.0.1
- @pandacss/dev: ^0.31.0
- @park-ui/panda-preset: ^0.33.0

- next: 14.1.0
- react: ^18
- react-dom: ^18

準備

  1. Next.js(App Router)とPanda CSSの導入
  2. インストール
  3. Panda ConfigファイルにPark UIプリセットを設定
  4. コンテキストファイルを配置
  5. TSConfigのパスとpark-ui.jsonを設定(任意)

0. Next.js(App Router)とPanda CSSの導入

1. インストール

ここからはPark UI公式ドキュメントのGetting Startedに沿って説明します。

# Ark UIをインストール
npm install @ark-ui/react

# Park UIのPanda Presetを作成
npm install --save-dev @park-ui/panda-preset

2. Panda ConfigファイルにPark UIプリセットを設定

ここではPanda CSSを使っているので、panda.config.tsにPark UIプリセットを追加します。

// panda.config.ts
import { defineConfig } from "@pandacss/dev";
import { createPreset } from "@park-ui/panda-preset";

export default defineConfig({
  preflight: true,
  presets: [
    "@pandacss/preset-base",
    createPreset({
      accentColor: "blue",
      grayColor: "sand",
      borderRadius: "xl",
    }),
    // or "@park-ui/panda-preset"
  ],
  include: ["./src/**/*.{js,jsx,ts,tsx}"],
  exclude: [],
  jsxFramework: "react",
  outdir: "styled-system",
});

この例ではcreatePreset関数を使ってアクセントカラーにblue、グレーカラーにsand、borderRadiusにxlを設定していますが、Park UIデフォルトのプリセットを使う場合は"@park-ui/panda-preset"という文字列を配列に記述すればOKです。

Park UIのプリセットによってPanda CSSのrecipespatternsを生成し、それをコンポーネントで利用するという仕組みです。

Colors - Park UI
park-ui.com

3. コンテキストファイルを配置

まずプロジェクト内のPark UIのコンポーネントを置くディレクトリと、Park UIコンテキストを置くディレクトリを決定します。この例では以下のように設定します。

  • Park UIコンポーネント: src/components/ui
  • Park UIコンテキスト: src/lib

Park UIコンテキストのディレクトリ(src/lib)にcreate-style-context.tsxを作成し、Park UIドキュメントからコピー&ペーストします。React Server Components(RSC)を使う場合は冒頭に"use client"ディレクティブを記載します。

4. TSConfigのパスとpark-ui.jsonを設定 (任意)

この設定はPark UI CLIを使う場合必要になります。

TSConfig

{
  "baseUrl": ".",
  "paths": {
    "@/*": ["./src/*"],
    "@styled-system/*": ["./styled-system/*"]
  }
}

park-ui.json

park-ui.jsonは後述するPark UI CLIを使用する場面で必要になります。Park UI CLIによる自動コピー機能を使わない場合は必要ありません。importAliasesには3.で決定したPark UIコンポーネントディレクトリと、Park UIコンテキストのディレクトリを設定します。

{
  "cssFramework": "panda",
  "jsFramework": "react",
  "importAliases": {
    "components": "@/components/ui",
    "utils": "@/lib"
  },
  "useReactServerComponents": true
}

コンポーネントの使い方

Park UIのコンポーネントは通常のUIライブラリとは異なり、コンポーネントのコードをディレクトリにコピー&ペーストして使用します。例えばPark UIの<Button>コンポーネントを使う場合、Park UIのウェブサイトに記載されているコードをコピーし、button.tsxとしてディレクトリの任意の場所に置く必要があります。

この例ではsrc/components/uiをPark UIコンポーネントのディレクトリとしているので、src/components/ui/button.tsxというファイルを作成して、下記リンクの「Installation」>「1. Add Component」のコードをコピー&ペーストします。

Button - Park UI
park-ui.com

具体的な使い方は各コンポーネントのUsageのコードを参考にするといいでしょう。

コンポーネントのProps

各コンポーネントのPropsの内容はArk UIのAPI Referenceを参照することになります。Park UIドキュメントの各コンポーネントのヘッダ画面にリンクが配置されています。

Park UI CLIによる自動コピー

Park UI CLIでは前述の通りコマンドラインによってコンポーネントの自動コピーが可能です。Park UI CLIを使うにはpark-ui.jsonが必要です。

# park-ui.jsonを生成
npx @park-ui/cli init

# buttonコンポーネントをコピー
npx @park-ui/cli add button

# 全てのPark UIコンポーネントをコピー
npx @park-ui/cli add --all
CLI - Park UI
park-ui.com

Park UI 使用における留意点

React Server Components (RSC)を使う場合

Park UIコンテキストに依存するコンポーネントには先頭に"use client"ディレクティブを記載する必要があります。Park UI CLIを使用する場合は、park-ui.jsonuseReactServerComponentstrueにしておくと自動コピーの際に必要なコンポーネントに対して"use client"ディレクティブを自動で付けてくれます。

独自のSemantic Tokens

Park UIはPanda CSSやTailwindのTokensの値を使って独自のSemantic Tokensを生成しています。ただしPanda CSSやTailwindのTokensを改変する形であるため、これらのツールを既に使ったことがある人にとっては少し引っかかるポイントになります。

  • パレットを12段階に新たに正規化している (例: red.50red.1になる)
  • パレットのshadesがダークモードで明暗が逆転する (例: ライトモードのred.12は暗色だがダークモードのred.12は明色)

この仕様は Radixのカラーシステム に則っているようです。

カスタマイズの方法

panda.config.tsで既存のテーマを拡張(extend)することでPark UIのプリセットをカスタマイズすることができます。

まとめ

Chakra UIは 2023年中にゼロランタイムCSS in JSの導入とRSCに対応するv3をリリースする予定でした が、2024年2月現在v3はリリースされていません。
Chakra UIは将来的に自前のゼロランタイムCSS in JSであるPanda CSSを導入する予定です。

2024/03/29追記 やはりChakra UI v3はPanda CSS + Ark UIで構成され、そしてコンポーネントデザインにはPark UIが採用されるようです。

また Material-UIも2024年6月までにv6をリリースし、ゼロランタイムCSS in JSの導入とRSCに対応する予定 です。

今後主流になっていくと思われるゼロランタイムCSS in JSやRSCの準備運動としてPark UIを使ってみてはいかがでしょうか。

リンク

Park UI
park-ui.com
Panda CSS
panda-css.com
Ark UI
ark-ui.com
Zag
zagjs.com

It Ain’t Over ‘til It’s Over / Lenny Kravitz (1991)

広告

2024年02月21日 最終更新日2024年03月28日

Park UI + Panda CSSでReact Server Components(RSC)に対応

技術記事

Top

水戸地図(β)