🐙

使いづらいと言わせないFigmaのコンポーネント設計

2024/07/14に公開

こんにちは。
普段はフロントエンドの開発を行いながら、デザイナーとデザインシステムの構築を行ったりしています。
デザイナーと仕事をするのが楽しい今日頃ごろです!

「Reactのコンポーネント設計はいろんな記事があるけど、Figmaのコンポーネント設計ってどうやってやればいいのか見つからない」と感じていました。
半年ほどデザインシステムのコンポーネント設計をデザイナーと一緒にやってきて、なんとなく知見が溜まって来たのでまとめようと思います。

前提

<ツール・技術>

  • デザインツール: Figma
  • フロントエンド: React・Typescript
  • UIライブラリ: MUI

<組織>
デザイナー数名とエンジニア1名。
デザイナーは全員美大出身で、コーディングは一切できません。
エンジニアは私のことです。

こんな人におすすめ

  • Figmaコンポーネントを作ってみたけど、使い勝手が悪い気がする
  • コンポーネントの設計って、どんなふうに行っていくのかわからない

コンポーネントで発生していた課題

実は、私が取り組む以前からデザインシステムは存在していました。
しかし、なかなか定着せず、エンジニアからの評判も悪かったです。

  • デザインシステムが頻繁に更新されていて、ついていけない
  • 似たUIが乱立し、コンポーネントという概念はあっても再利用できない
  • 数ピクセル単位の調整や、paddingなどを無視した視覚的な調整が多い
  • MUIの構造を無視しているため、実現するための工数がかかる

結局何がダメだったのか?

コンポーネント設計が局所最適になっていた

これが一番大きかったと思います。
コンポーネント設計時には、そのコンポーネントのことだけを一生懸命考えていました。
Buttonであれば、そのButton単体でのバランス感が最も重要でした。
しかし画面はさまざまなコンポーネントで構成されています。
そのときに初めて「何かうまくいかない」ということが見つかり、結局デザインシステムを直したり、コンポーネントを改変するなどの事態に陥っていました。

プロパティを設計していなかった

プロパティをデザイナーだけで設計するのは難しかったと思います。
(エンジニアでもPropsを正しく設計しろと言われると難しいのに。。。😭)
そのせいで、プロパティの変更によるコンポーネントの変化が正しくなかったり、結果的に実装が難しくなっていました。

コンポーネント設計時のポイント

コンポーネント同士の「近接」「整列」を確認する

デザインの4原則は知っている人も多いかと思います。

  1. 近接
  2. 整列
  3. 反復
  4. コントラスト

この中で、コンポーネントにとって最も関わってくるのは「近接」「整列」だと感じています。
特に複数種類のコンポーネントを使った場合にも「整列」が表現できているかは、確認しておくべきポイントです。
TextFieldとButton

上記はMUIのTextFieldとButtonを並べた例です。
TextFieldとButtonの高さが違うため、「整列」の観点が満たせません。
UI設計時にこの違いに気がつき、画面ごとに修正したり、再度コンポーネントを更新したりを繰り返していました。
そのため現在では、以下のコンポーネント同士は設計段階で並べても問題ないかを確認しています。

  • TextField
  • Button, IconButton
  • Radio, CheckBox
  • Switch
  • Typography
  • (DataGridの各セルに、それぞれのコンポーネントを入れても問題ないかも確認しています)

特にMUIではRadi,CheckBox,IconButtonではhoverエリアがあるため、HTML的な整列と視覚的な整列が違うため、注意が必要です。

※ Figmaを利用している場合は、線(border)の扱いが実装と違うことに注意してください。

<Figma>

  • オートレイアウト: 左右 16, 上下 8
  • 線: 2px

<実装>

  • box-sizing: "border-box";
  • padding: 8px 16px;
  • border: 2px;

一見同じような指定に見えますが、画像の通り高さ・横幅が変わります。
Figmaの場合、線がパディングに被る形で表現されてしまいます。
Figma側でのパディングを減らすなどで対応する必要があります。

プロパティ名を正しく設計する

プロパティ名を意識することで、自然とコンポーネントの状態変化にも敏感になります。
以下のルールを設けて運用しています。
英語が苦手なメンバーも多いので、緩めに設定をしています。
(この辺りの命名規則はリーダブルコードを参考にしています。デザイナーも読んで欲しい)

  • プロパティ名とコンポーネントが変化する内容を一致させる
    悪い例: colorを変化させると、Typographyの色と左右の余白が変化する
    -> この場合は、colorをTypographyのcolorの変化のみにし、余白を変化させるプロパティを追加するのが良い
    -> もしくは、colorではなく別のプロパティ名で両方が変化すしても違和感のないプロパティとする
    例) status, variantなど
  • プロパティ名はlowerCamelCase(先頭は小文字から始まり、単語を繋げるときは単語の先頭が大文字になる)で記述すること
  • ブール値の場合、ブール値だとわかりやすい名前にする
    • 何かが存在することを表す: hasVale, hasIcon などhasをつける
    • 可能かどうかを表す: clickable などenableをつける
    • その他: 困った時は最悪isをつける
  • ブール値の説明は、「どんな場合に何を表示する」かが伝わるように記述する
  • lowerCamelCaseで記述すること

その他、status,color,sizeなどで使える単語も規定しています。

Typographyを中心にコンポーネントの利用ルールを作る

結論として、Typographyのサイズに合わせて各コンポーネントのsizeを決めるというルールにしました。
Typographyがない画面はないですし、読みやすさなどの観点から最初に決まるのがTypographyであるため、このルールを採用しました。

  • Buttonなどテキストを持つコンポーネントはTypographyと同じfont-sizeになるものを選ぶ
    • Typographyと横並びになる場合には、横並びになるfont-sizeで合わせる
    • 横並びにならない場合には、画面のベースとなるfont-sizeに合わせる
  • テキストを持たないコンポーネントは、Buttonのsizeと合わせる
    • もしButtonが存在することを仮定し、Buttonのsizeが"regular"となるのであれば、その他のコンポーネントのsizeも"regular"とする

ルールを決めるにあたり、デザイナーに 「コンポーネントのサイズはどうやって決めるのか?」 というところを言語化してもらいました。
エンジニアには理解しづらい「こっちの方が統一感がある」「余白が広いから」という理由で、コンポーネントのサイズを変更することを禁止するようにしています。
(余白などの値も同様に言語化し、ルール化しています)

まとめ

基本的には、「UI設計を行うために、コンポーネントはどんな要件を満たすべきか」 ということを考えています。
そのために、UI設計を行う際の原則はなんなのか、デザイナーはどんなことを考えながらコンポーネントを利用しているのか、ということを言語化・ルール化を大事に動いています。
その根底には、「UI設計を属人化させず、将来的にはエンジニアでさえ関われるようにしたい」 という思いがあります。
実現するためには設計だけではもちろん不十分で、さまざまな活動を並行して行っています。
それはまた別の記事として記録しておこうと思います。

Discussion