2025年12月12日
デジタル庁デザインシステムをArk UI + Panda CSSで実装する
デジタル庁が公開しているデザインシステムは、日本の行政サービスにおけるUI・UXを統一することを目的に策定されたガイドラインであり、アクセシビリティ、再現性、統一感を重視した設計が特徴です。本記事では、このデザインシステムを Ark UI と Panda CSS を用いて実装する方法を紹介します。
さらに、この実装を通じて、Panda CSS を活用したテーマ構築や、Ark UI を利用したコンポーネントライブラリの作成手法についても解説します。
読者がすでに Panda CSS に関する基本的な知識を持っていることを前提に進めます。
用語
まず、デジタル庁デザインシステムとは、日本の行政サービスにおける統一的なUI/UXを提供するためにデジタル庁が策定したデザインルールとコンポーネントガイドラインの総称です。Figmaライブラリやコード実装指針が公開されており、アクセシビリティ対応が強く求められています。
Ark UI は Chakra UI の開発チームが提供しているヘッドレスな UI ライブラリで、状態管理やキーボード操作などのロジックをコンポーネントとして提供します。HTML構造やスタイルは利用者が自由に定義できるため、本記事のようにデザインシステムに沿った実装を行う際に大きな柔軟性があります。
Panda CSS は Chakra UI の思想を継承した型安全なCSS-in-JSライブラリで、Tailwind CSS のようにユーティリティクラスを扱いつつ、TypeScript の補完機能を維持し、テーマベースのスタイル管理を行える点が特徴です。Recipe や条件付きスタイルなど、再利用性の高いスタイル構築機能も備えています。
動機
本記事で Ark UI と Panda CSS を採用する主な理由は、デジタル庁デザインシステムの React 実装が Tailwind CSS でスクラッチされており、そのままでは汎用性が高くないためです。ヘッドレスUIライブラリである Ark UI に置き換えることで、UIロジックとスタイルを分離でき、保守性を向上させられます。
加えて、Panda CSS を利用することで構造とスタイルの明確な分離が可能になります。Tailwind CSS では DOM 構造とクラス名が密結合しがちですが、Panda CSS の Recipe や Slot Recipe を用いることで、構造を変えずにスタイルだけを安全に管理できます。これは、デザインシステムに準拠したコンポーネントを量産する場合に大きな利点となります。
さらに、デジタル庁デザインシステムはアクセシビリティ要件(WCAG 2.1 AA)への準拠を重視しているため、もともと ARIA 対応が組み込まれている Ark UI との相性が非常に良いというメリットもあります。フォーカス管理やロール付与などが標準で整っており、この点は自前で実装すると大きなコストがかかります。
環境
- "@ark-ui/react": ">=5.0.0"
- "@pandacss/dev": ">=1.0.0"
- "react": ">=19.0.0"
- "typescript": ">=5.0.0"
Panda CSS は、JSX Style Context を使用するため v1 系が必須となります。
必要な作業
デジタル庁デザインシステムを Ark UI + Panda CSS へ移植するうえで、次の作業が必要になります。
- デジタル庁デザインシステムのトークンを Panda CSS で扱える形に変換
- Panda CSS レシピの作成
- コンポーネントコレクションの作成
プロジェクト構成
.
├── apps
│ └── nextjs
├── components // 3.を実装
│ ├── src
│ └── stories
├── package.json
└── packages
├── cli
├── generated
├── preset // 2.を実装
└── preset-base // 1.を実装
この記事ではライブラリとしてnpmに公開することを前提としているため、上記のような monorepo でプロジェクトを構成します。
なお、このプロジェクト構成は、Ark UI を Panda CSS でスタイリングしている UI ライブラリ「Park UI」に大きな影響を受けています。
1. デジタル庁デザインシステムのトークンを Panda CSS で扱える形に変換
第一に、デザインシステムのトークンを Panda CSS で扱える形に変換します。デザイントークンは npm パッケージとして提供されているため、これを dependencies にインストールし、色や余白、タイポグラフィなどのトークンを tokens、semanticTokens、utilities、textStyles として定義します。
トークンの定義 (tokens)
// トークンの使用例
const buttonStyle = css({
bg: { base: "blue.primary", _hover: "blue.secondary" },
color: "white",
});
トークン定義では、デザインシステムのカラーパレットに基づき、プライマリー、セカンダリー、ターシャリー、背景色などを設定します。デジタル庁のカラートークンはコントラスト比の要件が異なるため、各色相ごとに適切な明度を選定する必要があります。
タイポグラフィの定義 (textStyles)
// テキストスタイルの使用例
const paragraphStyle = css({ textStyle: "std-17N-170" });
タイポグラフィトークンでは、デジタル庁が定義するテキストスタイルを Panda CSS の Text Styles にマッピングします。テキストスタイル・フォントサイズ・太さ・行高といった情報を組み合わせることで、記事内のコード例のように textStyle: "std-17N-170" の形式で利用できるようになります。
ユーティリティの定義 (utilities)
// ユーティリティの使用例
const link = css({ _focusVisible: { focusRing: "calc(2 / 16 * 1rem)" } });
また、ユーティリティ定義では、デジタル庁デザインシステムで多用される Tailwind CSS の ring を模したスタイリングを行うために、新たに focusBox というユーティリティを定義します。行政サービス向けのUIはキーボード操作への対応が求められており、フォーカスリングの表現はアクセシビリティ上重要な要素です。
この記事では npm で公開することを目的としているため、これらの設定を Panda CSS のプリセットとしてエクスポートします。この基礎プリセットは、次項で作成するメインプリセットに包含されますが、単体で使用することも可能です。
2. Panda CSS レシピの作成
第二に、定義したトークンやユーティリティを使って Ark UI に適用するレシピを作成します。これは、単体コンポーネントには defineRecipe、複合コンポーネントには defineSlotRecipe を使用します。
デジタル庁デザインシステムのスニペットと対応する Ark UI のコンポーネントを照合し、対応がない場合はスニペットを参考に独自にパーツを定義します。
Panda CSS への移植に伴い、一つの工夫を行いました。デジタル庁デザインシステムの React 版のコードスニペットはブルーをキーカラーとして設計されていますが、もし他の色をキーカラーとして採用したい場合、blue で定義されている箇所をすべて置換する必要があります。そこで今回は、Panda CSS の Virtual Color 機能を利用し、コンポーネント単位やテーマ単位で柔軟に色をカスタマイズできる構成としました。
単体コンポーネントのレシピ例 (button)
https://github.com/cieloazul310/digital-go-design-system-with-panda/blob/main/packages/preset/src/recipes/button.ts
複合コンポーネントのレシピ例 (accordion)
https://github.com/cieloazul310/digital-go-design-system-with-panda/blob/main/packages/preset/src/recipes/accordion.ts
複合コンポーネント(Ark UIに対応するコンポーネントがない場合)のレシピ例 (card)
https://github.com/cieloazul310/digital-go-design-system-with-panda/blob/main/packages/preset/src/recipes/card.ts
この記事では npm で公開することを目的としているため、前項と同様にこれらの設定を Panda CSS のプリセットとしてエクスポートします。また、キーカラーを柔軟に設定できるよう、プリセットに加えて createPreset 関数を作成し、あわせてエクスポートしています。
// panda.config.ts
import { defineConfig } from "@pandacss/dev";
import { createPreset } from "@cieloazul310/digital-go-pandacss-preset";
export default defineConfig({
presets: [createPreset("blue")],
// ...pandaConfig
});
3. コンポーネントコレクションの作成
第三に、作成したレシピを適用した UI コンポーネントコレクションを構築します。Panda CSS v1 から正式採用された JSX Style Context を使うことで、Ark UI のコンポーネントにレシピを直接適用できます。単体コンポーネントでは、styled 関数で Ark UI コンポーネントにレシピを紐付け、複合コンポーネントでは withProvider と withContext を用いてパーツごとのスタイルを適用します。
JSX Style Contextについては以下の記事で解説しています。
単体コンポーネントにレシピを適用する例 (<Button>)
https://github.com/cieloazul310/digital-go-design-system-with-panda/blob/main/components/src/button/snippet.tsx
複合コンポーネントにレシピを適用する例 (<Accordion>)
https://github.com/cieloazul310/digital-go-design-system-with-panda/blob/main/components/src/accordion/snippet.tsx
複合コンポーネント(Ark UIに対応するコンポーネントがない場合)にレシピを適用する例 (<Card>)
https://github.com/cieloazul310/digital-go-design-system-with-panda/blob/main/components/src/card/snippet.tsx
コンポーネントコレクションは npm パッケージとして配布するのではなく、shadcn/ui のように CLI を用いてプロジェクト内に生成する方式を採用しています。これにより、バージョンアップ時の影響範囲を制御しやすく、各プロジェクトに合わせて柔軟にカスタマイズできます。
別途プロジェクト内にコンポーネントを生成するための CLI パッケージを作成していますが、デジタル庁デザインシステムを Ark UI + Panda CSS で実装するという本筋とは離れるため説明は省きます。
課題
デジタル庁デザインシステムのコードスニペットと Ark UI の複合コンポーネントは設計思想が異なるため、完全な一致が難しく、対応付けに手間がかかります。また、デザインシステム側のスニペットが更新された場合、反映作業を手動で行う必要があるため、メンテナンスコストが発生することが課題です。
まとめ
以上の手順と構成により、デジタル庁デザインシステムを Ark UI と Panda CSS で実装する方法を提示しました。Ark UI と Panda CSS を用いたコンポーネントライブラリの作成については、本記事では十分に説明し切れていない部分もありますが、詳細が気になる方は GitHub リポジトリの構成をご確認ください。
本記事が、UI ライブラリの構築やデザインシステムの運用に取り組む開発者の参考になれば幸いです。
Squeaky Wheel / James Ellis Ford (2023)
Panda CSS
Panda CSSは型安全を保ちながらスタイルを記述することができるCSS-in-JSのパッケージです。
https://panda-css.com/