🐪

Dev ModeのPlaygroundを活用したReact Component設計

2024/06/23に公開

最近、FigmaのDev ModeのPlaygroundを使用する機会があり、こちらが便利だと感じたので紹介させていただきます。

サマリー

  • 開発とFigmaデザインの不一致で、保守性が下がることがある。Dev ModeのPlaygroundを使うことで改善できそう。
  • Playgroundとは、FigmaデザインのComponent Propeatyを簡単に試すことができるツール
  • こちらを使用して設計することで、開発の保守性・効率が上がることが期待できる

よくある設計方法とその課題

以下のようなButtonを設計する際、どのような設計方法があるでしょうか。

色が背景または、枠線に表示されるパターンがあったり、テキストの横にアイコンがあったりと複数の状態があるようです。
エンジニアが目視で複数の状態を比較し、それを以下のようなPropsとして定義して実装を進めるようなやり方があると思います。

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
    // TRUEの場合は、背景色が塗られる。FALSEの場合は、枠線が塗られる。
    isContained: boolean,
    // テキストの左にアイコンを表示する
    icon: ReactNode
}

エンジニアが設計します。このため、開発の容易性・実現性が向上するというメリットがある一方で、以下のような課題が生じ得ます。

  • 開発効率の懸念: 数十個と、あるようなコンポーネントに対してこのような比較を行うことは、それなりに時間がかかる
  • 保守性の懸念: 今後、Figmaデザイン側で新しい状態が用意された際に、開発側がスムーズに対応できない場合がある

例えば、開発後にFigmaデザイン側がこのように更新されたとします。

色の表示を切り替える状態が、2パターン→5パターンに増えました。

開発側でこちらの色の状態はBooleanで管理していたため、3パターン以上を表現できません。このため、Stringに変更する必要があります。

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
    // 値に応じて、色が塗られる箇所が切り替わる
    variant: "contained" | "outlined" | "text" | ...
    // テキストの左にアイコンを表示する
    icon: ReactNode
}

Propsの変更は、中身の実装を大きく変更する必要があります。これはできれば避けたいです。
このような課題を解決するために、FigmaデザインのComponent Propertiesを確認して一致させる手法があります。Playgroundはこれを効率的に行うことができる機能です。

Playgroundとは

PlaygroundはFigmaデザインのComponent Propertiesを確認・検証することができるFigma dev modeの機能です。
Component Propertiesは、コンポーネントの特定の状態を制御するための機能です。こちらを使用すすることで、デザイン要素の一貫性を保ちながら、簡単にカスタマイズや調整が可能になります。
赤枠の部分から確認できます。

Playgroundを使用すると、このように確認できます。(画質悪く、すみません)

こちらを使うと、Figmaの使い方に慣れていないエンジニアでも容易に確認することができようになります。デザインとの一貫性を保ちやすくなるため、デザインシステム構築にも大変有用です。
※こちらはDev Modeを使用が前提です。

Playgroundを活用した設計

具体的にどのように活用するかについて。こちらは、基本的にはそのままコードに起こしつつ、実装側の都合も考慮し、意図的にFigmaデザインと異なるように調整するのが良いと思います。

例えば、以下のように確認できる場合。

これをそのままPropsに起こすとこのようになります。

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
    // 値に応じて、色が塗られる箇所が切り替わる
    style: "filled" | "outlined" | "text" | "elevated" | "tonal"
    //ユーザーの操作によって変化する
    state: "enabled" | "hovered" | "focused" | "pressed" | "disabled"
    // テキストの左にアイコンを表示する
    showIcon: boolean
    // 中身のテキスト
    labelText: string
}

呼び出し側はこのようになります。

<Button
    style="outlined"
    state="hovered"
    showIcon={true}
    labelText="決定"
/>

非常にデザインと一致していて、良さそうに見えますが、これはこれで実装が進めづらいです。
具体的には、以下のような課題があります。

  • stylePropsは、Inline Styleを定義するstyle属性と競合してしまう
  • statePropsは、擬似クラスとして扱えるため、Propsで受け取る必要がない
/* hover擬似クラスの使用 */ 
.button:hover {
    background: #79747E;
}
  • showIconPropsは、Booleanのため、表示するアイコンの柔軟性に欠ける
  • labelTextPropsは、中身のコンテンツを定義する属性として直感的でない

これを防ぐために、このように設計するなどが考えられます。

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
+    // 値に応じて、色が塗られる箇所が切り替わる
+    variant: "filled" | "outlined" | "text" | "elevated" | "tonal"
+    // テキストの左にアイコンを表示する
+    icon: ReactNode
+    // 中身のコンテンツ
+    children: ReactNode
-    // 値に応じて、色が塗られる箇所が切り替わる
-    style: "filled" | "outlined" | "text" | "elevated" | "tonal"
-    //ユーザーの操作によって変化する
-    state: "enabled" | "hovered" | "focused" | "pressed" | "disabled"
-    // テキストの左にアイコンを表示する
-    showIcon: boolean
-    // 中身のテキスト
-    labelText: string
}

このような調整作業については、MUIMantineなどのあらゆるUIライブラリが参考になります。

改めて、呼び出し側はこのようになります。使い勝手が改善されましたね。

- <Button
-     style="outlined"
-     state="hovered"
-     showIcon={true}
-     labelText="決定"
- />
+ <Button
+     variant="outlined"
+     icon={<ArrowLeft />}
+ >
+     決定
+ </Button>

このように進めることで、実現容易性を維持したままFigmaデザインとの一貫性を強固にすることができます。

また、「ここまで調整するなら、最初から全てエンジニアが設計すれば良いのでは!?」、とのように慣れている方は感じるかもしれません。実際、Buttonのような比較的シンプルなコンポーネントではそこまで恩恵を受けづらいです。Card、Dialogなどより粒度が大きいコンポーネントであるほど、こちらの効果が期待できるかと思います。

エンジニアだけで設計することに比べて、設計の雛形が用意されているので開発効率が向上し、また保守性の向上にも期待できます。嬉しい!

今後

今後(数年後)は、React Componentの設計にはFigmaのCode connectを活用することが主流になりそうかなと感じています。

Code Connect は、コード内のデザインシステムコンポーネントをFigmaのデザインシステムに接続するためのツールです。

https://www.figma.com/ja-jp/blog/introducing-code-connect/

Code ConnectはFigmaデザインと開発のギャップを埋める機能です。Component Propertiesなどを読み取って、React Componentの雛形を自動で作成、それをFigmaデザイン上で確認できるようにすることが出来るようになります。現状はベータです。

簡単に使い方を説明します。
コマンド入力でこのように、FigmaからReact Componentの雛形を用意してくれます。エンジニアはこれを適宜調整します。

import React from "react"
import { Button } from "./Button"
import figma from "@figma/code-connect"

/**
 * -- This file was auto-generated by `figma connect create` --
 * `props` includes a mapping from Figma properties and variants to
 * suggested values. You should update this to match the props of your
 * code component, and update the `example` function to return the
 * code example you'd like to see in Figma
 */

figma.connect(
  Button,
  "https://www.figma.com/design/...",
  {
    props: {
      labeltext: figma.string("Label text"),
      icon: figma.instance("Icon"),
      style: figma.enum("Style", {
        Filled: "filled",
        Outlined: "outlined",
        Text: "text",
        Elevated: "elevated",
        Tonal: "tonal",
      }),
      state: figma.enum("State", {
        enabled: "enabled",
        hovered: "hovered",
        focused: "focused",
        pressed: "pressed",
        disabled: "disabled",
      }),
      showIcon: figma.boolean("Show Icon"),
    },
    example: (props) => <Button />,
  },
)

また、Figma側にこちらを反映できます。
これにより、Figma上でコンポーネントを選択すると、それのコードを確認できようになります。

ページの実装を進める際に、Figmaに表示されたコンポーネントを呼び出す際に、こちらのコードをコピペして使用することで品質を維持したまま開発効率を向上させることが期待できそうです。

Reactでの使い方の詳細について、こちらに詳細が記載されています。
よくあるAI生成ツールは、精度が微妙なことがありますが、こちらはとても精度が良いので普通に使えそうです。

おわりに

Dev Modeにはこちら以外にも、アノテーションやVSCode拡張機能などの機能があります。私はインスペクト確認やPlayground機能しか現状は使っていないため、他機能も試し、また記事しようと思います🖐️

参考

https://note.com/hikarutayama/n/nd61c99de4972

https://note.com/fjkn/n/nfa218f39413e

https://engineering.linecorp.com/ja/blog/figma-dev-mode-and-variables

https://www.figma.com/ja-jp/dev-mode/

https://www.figma.com/community/file/1035203688168086460/material-3-design-kit

NCDCエンジニアブログ

Discussion