「スピード」と「こだわり」を両立したい!shadcn/uiとTailwind CSSを活用したゼロからのコンポーネントライブラリ構築

こんにちは、10X プロダクトデザイナーの日比谷(@suuminbot)です。

現在10Xでは新規プロダクトを複数開発している真っ只中ですが、私もその一環でshadcn/uiとTailwind CSSを活用しつつ、SaaSのサービス画面(管理画面)用のコンポーネントライブラリをゼロから構築していました。

少し前に一通り最低限必要なコンポーネントをFigma・実装ともに作りきり、現在は実際にそのコンポーネントライブラリを使って自分自身が複数のプロダクトのUIを作ったり、開発が進んでいる様子を見ているところです。

このブログでは、今回取り組んだことや学びをご紹介していこうと思います。

新規構築の経緯

10Xの主力事業であるStailerのサービス画面(小売企業の方々が利用する管理画面)はNuxt.jsとBulma(Vuefy)で作られています。今回の新規プロダクト開発にあたっては、@kitakさんが中心となりTypescript・Remixベースでの開発に移行することとなり、併せてコンポーネントライブラリも新しく構築する運びとなりました。

外部コンポーネントライブラリのあるある課題

これまでのStailerや、自分自身が過去携わってきたプロダクトでも、特にデスクトップ利用を想定した業務用Webアプリケーションは外部のコンポーネントライブラリを利用することがありますが、立ち上げそのものはクイックに済むものの、その後の運用で大きな課題を感じることが多かったです。

  • 用意されているコンポーネントライブラリ・デザイントークンだと不十分
    • 種類が足りない、見た目を変えたい等
  • コードとFigmaの一致を保つのが大変
  • コンポーネントの粒度が使いづらい
  • 何はいじれて何はいじれないのかよく分からない

自分たちのプロダクトに合った形のコンポーネントライブラリを、クイックに立ち上げたい

yamottyさんのブログにあるように、10Xでは現在小売企業の変革を推し進めるため、複数のプロダクトを開発しようとしています。(いわゆる"コンパウンドスタートアップ"なのか?)

そんな我々が過去の学びを活かしつつ今回の新規コンポーネントライブラリの構築で実現したいことは次の4つにありました。

  1. コンポーネントライブラリの構築そのものに時間をかけない
  2. こだわりたいコンポーネントは自分たちのサービスに合わせた形で作成・改修する
  3. デザインと実装の見た目と構造を一致させる
  4. 迷いなくデザイン・実装できる

「クイックな立ち上げ」と「こだわり」を両立できるshadcn/ui

他にもいくつかの選択肢がありましたが、今回我々はshadcn/uiを使ったコンポーネントライブラリを構築することとしました。

shadcn/uiは次のような特徴を持ったライブラリです。

  • 好きなコンポーネントだけを導入できるコンポーネントライブラリ
    • 従来のUIライブラリはフルパッケージのインストールを必要としますが、shadcn/uiは開発者が個別のコンポーネントをプロジェクトに直接コピー&ペーストできます
  • 柔軟にカスタマイズ可能
    • コンポーネントのコードはプロジェクトの中にコピー&ペーストして使うため、要件にあわせてスタイルや機能を柔軟にカスタマイズできます
  • ミニマムで使い勝手の良いデザイン
    • shadcn/uiそのもののデザインがシンプル・ミニマムでそのままでも十分使いやすいです
  • Tailwind・Radix UIをベースとした実装

ここからは、実際に取り組んだことをご紹介します。

1. Figmaでのセットアップ

まず最初にFigma側でコンポーネントを作っていくための基盤を整えつつ、ゴリゴリと我々に必要なコンポーネントを洗っていきました。

1-1. TailwindのclassをwrapするSemantic Tokenを用意する

shadcn/uiはTailwindを採用しているので、必然的に我々もTailwindを利用することになります。Tailwindは「ユーティリティファースト」を掲げており、次のようなユーティリティなclass設計を採用しています。

.text-slate-950 .text-2xl

こういったユーティリティベースな命名は汎用的ではあるものの、複数人のメンバーでデザイン・開発するにあたってはどこに何をどう使えばいいのかブレる原因となってしまうため、一部の要素については自社オリジナルの定義を使うことにしました。

現在自社オリジナルの定義を使っているのは、経験上特に利用回数が多くブレやすいタイポグラフィと色に関する指定です。*1

特にタイポグラフィでは、見出しと本文とで当てたいline-heightも異なるため、それらをまとめて指定しておくためにもカスタム定義をつけておくのは重要だと感じました。

1-2. Figmaにshadcn/uiのコンポーネントを起こしつつ、こだわりたいコンポーネントに調整・追加していく

shadcn/uiには公開されているFigmaライブラリが複数ありますが、多くのコンポーネントを自分たちで調整したり、新しく追加したりしたかったため、必要なコンポーネントのデザインをすべて自分で起こすことを選択しました。

まずボタンやフォーム系の基本的なコンポーネントを作った後、直近必要な画面のデザインを作り、その画面を作る過程で必要になった汎用パーツをライブラリ側に作り…の繰り返しで、一連の作業の中でこれが一番時間がかかったと思います。

現行のデザインシステムの反省点を踏まえて、特に汎用的で広く使うコンポーネントについては

  • サイズ設定
  • 色設定
  • サブ要素の表示オプションの追加

など、柔軟性高く利用できるようにしました。

1-3. 実装とFigmaの一致を追求する

Buttonコンポーネントのプロパティの例

すべてのコンポーネントでFigmaとコードの一致を追求しました。

一致させたいのは次のような項目です。

  • 見た目そのもの
  • コンポーネント名
  • プロパティ名

とても地道な取り組みですが、デザイナ・開発双方にとって恩恵が大きいと感じています。

  • 開発視点:
    • 開発(とQA)時の迷いが減る
    • 実装後の手戻りが減る
  • デザイナー視点:
    • コンポーネント設計にエンジニアからのFBを受けられる
    • より実装に近い形でプロトタイプによるUI検証を実施できる

2. コードのセットアップ

作ったコンポーネントのデザインにあわせてごりごりコンポーネントの実装(マークアップ)を進めました。

まずは追加したいコンポーネントをshadcn/uiからインストールしてきます。

npx shadcn@latest add button

このままカスタムすることがなければこれでもうコンポーネントが完成です!とんでもなく楽ですね…!

例えば上記のようなコンポーネントは、色やフォントの指定を独自のものに置き換えただけで、後はすべてshadcn/uiのまま使っています。

3. コンポーネントライブラリの構築にデザイナもコミットするための、ワークフローの取り組み

今回の一連の取り組みで最もこれまでのやり方と異なったのは、デザイナーもコードを書いてコンポーネントを作っていくという点です。

まずFigmaでデザインをし、それをマークアップし、ブラウザで触ってみて確かめ、違うなというところをFigmaに反映する…といった感じで、デザインと実装をスピーディーに行き来するのは立ち上げ期においてとても重要だと感じています。*2

そういったワークフローに関するその他のtryについてもご紹介します。

Storybookの導入

コンポーネントカタログとしてStorybookを導入しました。(SWEの@sinamon129さんがしゅっと導入してくれました🥹)

実際の画面を作らずとも、バリエーションごとにコンポーネントの表示やインタラクションをデザイナーが確認しながら実装調整をすることができるようになりました。

デザイナーが実際の画面を開発するとなるとまた少しハードルが上がりますが、コンポーネント単位での実装をより気軽に行えるようにしてくれたのでとっても感謝しています。

コンポーネントへのフィードバックをもらう

コンポーネントそのものへのフィードバックをお願いしたり、アプリケーション側を実装してみての使いづらい点を気軽に出してもらっています。

いつもフィードバックをくれたり、相談にのってくれる@ryo_ryoo_ryoooさん@kitakさん@sinamon129さんには感謝しかありません。

FigmaのDevモードの導入

VariablesにTailwindの値を入れているので、脳内での値変換も不要

これまで社内ではFigmaのDevモードを導入していなかったのですが、Figma側でコンポーネントのプロパティを実装と揃えたり、Tailwindの値を指定して作っているなら、それをエンジニアにもより簡単にキャッチアップしてもらいたい!と思いDevモードの導入を決めました。

コンポーネントのplaygroundもそうですが、そもそものデザイン指定の値がとっても見やすくなり、デザイナー・エンジニア間のコミュニケーションは相当にやりやすくなったと感じます。

現在社内でDevモードを使っているエンジニアは直近頻繁にフロントエンド開発をする方のみですが、アンケートを実施したところエンジニアさんからの意見もとても好評でした。

  • もうDevモードがない状態には戻れません
  • あった方がとても効率がいいので引き続き使いたいです🥺

(社内アンケートの自由記述からの抜粋)

作りながらデザインパターンとデザイン原則も決めていく

コンポーネントライブラリをサクッと立ち上げられたおかげで、自分自身も早い段階で新規開発する複数のプロダクトのUXやUIを組み立てていく業務に集中することができました。

その過程で、デザインパターンとデザイン原則の定義も進めることができ、複数プロダクトをまたいでの体験の一貫性や、気をつけるべきことを認識できています。

作りながら定義していっているデザインパターン

結論: 現時点ではとても良い!

技術的背景からこれまであったデザインシステムが使えず、ゼロからコンポーネントライブラリをスピーディーに構築せなばならない…となると、当初は「本当にできるのかな…?」ときっとエンジニアさんも不安に思われた部分が多々あったと思います。

蓋を開けてみると、技術選定のためのトライアルも含め2ヶ月ほど*3で一通りの構築を実現でき、実際に利用してプロダクトをゴリゴリ作っていくフェーズに入ることができるようになりました。また、当社に合った形のコンポーネントライブラリが構築できたなと感じています。

これから更に開発・運用が進みまた課題が出てくるとは思いますが、「一貫性を担保しつつスピーディーに画面構築ができるコンポーネントライブラリ」のため、今後も継続的に改善していけたらと思います。

10Xではプロダクトデザイナーを募集しています

現在マルチプロダクト化を推し進めている真っ只中で、デザイナーとして挑戦できることが多々あります!フルタイム2人目のプロダクトデザイナーとして一緒にやっていきたいという方を募集しています💥(コードが書けなくてもOKだし、書いていきたいという方もWelcomeです!)

  • 選考に興味がある
  • 転職するかは分からないけど詳細聞きたい
  • デザインシステム・コンポーネントライブラリのことについて話したい

…そんな方は是非お気軽にユートラもしくはXのDMから話しかけてください!

youtrust.jp

*1:shadow, border-radius についてはそのままTailwindの値を利用しています。

*2:社内にフロントエンド領域にフォーカスできる方が在籍していたら別かもしれませんが、弊社の場合スタートアップで一人が様々な領域に越境することが求められるというのも大きいなーと

*3:2ヶ月これだけやってたのではなく、新規プロダクトのUIデザインやその他の業務もやっていた