entry-header-eye-catch.html
entry-title-container.html

entry-header-author-info.html
Article by

pixiv のデザインシステム実装『charcoal』を OSS 化します

こんにちは、@f_subal です。普段はおもに pixivFACTORY のフロントエンドを見たり、社内のデザインシステム整備の仕事をやったりしています。

さて、2021年に開催した弊社カンファレンス #pixivdevmeetup にて発表しましたデザインシステムの Web 版実装が先日 OSS 化されました 🎉 1。GitHub と npm から利用できます。

github.com

www.npmjs.com

発表時点では「pixiv-elements」という名称でしたが、公開にあたって「charcoal」という名前になりました。「charcoal(木炭)」とはデッサンの道具であり、線を引く、表現の基礎となる素材の一つです。また創作物を主役とするサービスの基盤として、それ自体は色を持たないモノクロの素材である、というニュアンスも含みます。

(ただし、npm パッケージのスコープは @charcoal-ui/ ですので注意してください。)

charcoal の実体は複数の npm パッケージの集合であり、以下これらの各パッケージについて紹介して行きます。

ユーティリティファーストと三層構造

inside.pixiv.blog

昨年の発表でもお話したとおり、ピクシブのデザインシステムはユーティリティファースト(より正確には、定数・ユーティリティ・コンポーネントの三層構造)で設計されています。 ユーティリティファーストの CSS フレームワークとしては Tailwind.css が有名ですが、charcoal では Tailwind.css 含め、2つのユーティリティ実装を提供しています。以下それぞれ紹介します。

まずは @charcoal-ui/tailwind-config です。これは charcoal のカラーテーマやスペーシングなどの定数を元に tailwind.config.js を生成するライブラリです。これにより、デザインシステムに沿ったクラスを使ったマークアップが可能になります。

Tailwind.css はピュアな CSS を吐き出すので、React はもちろん Vue.js や昔ながらの html テンプレートでも用いることができます。ピクシブは全社でフロントエンドの技術スタックを統一しているわけではないので、Tailwind 版を置くことでデザインシステムの導入ハードルを下げています。

次に @charcoal-ui/styled です。こちらは charcoal のカラーテーマやスペーシングに従う専用の記法を styled-components 内で利用可能にするライブラリです。詳しくは以下の記事を見てほしいのですが、たとえば o.text.brand と書くことでそのコンポーネントの文字色がブランドカラーになります。

inside.pixiv.blog

ピクシブでは pixiv.net のリニューアル他、フロントエンドのモダン化で React + styled-components が数多く採用されてきた経緯があります。そういうプロダクトで Tailwind.css と同様の恩恵を受けられるようにするのがこのライブラリの狙いです。


ところで、styledtailwind-config は両方とも同じ定数群を土台にしています。これら定数のみを扱うパッケージとして @charcoal-ui/foundation @charcoal-ui/theme の2つがあります。

@charcoal-ui/foundation は定数(色、スペーシング、文字サイズ、ブレイクポイントなど)を個別に定義します。@charcoal-ui/theme はその内容を、ユーティリティやコンポーネントが要求するテーマオブジェクトにまとめあげて提供します。

ユーティリティの実装が変わっても、依存している定数集が同じなので最終的な CSS はだいたい揃うことが保証されます。

他にもたくさんのライブラリがありますが、全体像は以下のとおりです。

📂 packages/
    # 定数のパッケージ
    📁 foundation/         #=> 全プロダクトで共通の定数(スペーシングやフォントサイズ)を提供
    📁 theme/              #=> foundation の定数をまとめあげたテーマオブジェクトとその型を提供

    # ユーティリティのパッケージ
    📁 styled/             #=> styled-components 向けの記法を定数から生成
    📁 tailwind-config/    #=> Tailwind.css のクラスを定数から生成する config を提供

    # コンポーネントのパッケージ
    📁 icons/              #=> SVG アイコン集。Custom Elements を提供する。
    📁 react/              #=> React 向けコンポーネント集。内部では styled を使用。
    📁 react-sandbox/      #=> @charcoal-ui/react にまだ収録されない実験的コンポーネント集

    # その他
    📁 icons-cli/          #=> Figma から SVG をダウンロードして icons を自動更新する bot
    📁 tailwind-diff-cli/  #=> 2つの tailwind.config.js を比較し、クラスの差分を表示する CLI
    📁 utils/              #=> 主に内部で使う便利関数集

charcoal のはじめかた

charcoal を導入する場合は、自分たちの技術スタックに応じてまず tailwind-configstyled を選択する必要があります。だいたい以下のフローチャートに従えば良いでしょう。実際にピクシブの各プロダクトではほぼ半々で選ばれている状況です。 詳しいインストール手順は GitHub の各パッケージの README.md か、ドキュメントサイトを見てください。重要なのは、最初にどっちのパッケージをインストールするかがプロジェクトによって異なるという点です。

pixiv.github.io

github.com

ユーティリティをインストールすることで、自分でコンポーネントを書く際に見た目を規約に従わせることができます。ただし、ある程度出来合いのコンポーネントが欲しい場合は、追加の選択肢として @charcoal-ui/react ないし @charcoal-ui/react-sandbox といったコンポーネント集を入れることができます。

@charcoal-ui/react-sandbox は、 @charcoal-ui/react にまだ収録されない実験的なコンポーネント集です。近い例として Material UI における Material UI Lab のようなものと考えることができます。)

現状では、 @charcoal-ui/icons を除いてコンポーネント集は React 向けのみです。

また @charcoal-ui/react 内部では styled を利用しているため、利用にあたっては styled-components のインストールも必要になります。

実際にどういうものがコンポーネントとして提供されているかについては以下の Storybook をご覧ください。

pixiv.github.io

今後どうしていきたいか

charcoal はユーティリティファーストなデザインシステムとしてある程度便利に使えるようになりました。

一方で、出来合いのコンポーネントについては今後充実させていく必要があるでしょう。「コンポーネントを組み合わせるだけで簡単に pixiv っぽい見た目のアプリケーションが作れる」ぐらいまで持っていけるとかなり成熟したライブラリになるんじゃないかと思います。

また今回は実装部分だけの公開でしたが、デザインとしての思想に関するドキュメントや Figma ファイルそのものなど、他のリソースも含むより包括的なデザインシステムの公開も目指していけたらと思っています。

GitHub 上での皆様のコントリビューションは歓迎しています。charcoal にコントリビュートしてみたい方はリポジトリの README に沿って是非 Issue の報告や Pull Request などをしていただければと思います。

あるいは社員としてデザインシステムの開発に関わりたい、プロダクト開発で利用してみたいという方は、フロントエンドエンジニアまたはプロダクトデザイナーでのご応募もお待ちしております!

hrmos.co


  1. 今回は Figma などの公開はしておりません。ライブラリのみです。
20191219021843
f_subal
2016年新卒入社。sensei by pixiv の開発や pixiv 本体投稿画面リニューアルなどを経て、pixivFACTORY のエンジニアをしている。百合と TypeScript が好き。