Figmaの「Conditional Logic」を限界まで使い倒す:状態を持つ完全インタラクティブなECカートの構築とデザインシステム統合
UI/UXデザイナーとフロントエンドエンジニアの間に存在する「プロトタイプの溝」——それは、プロトタイプが単なる「画面の紙芝居(静的遷移)」に過ぎず、実際のロジックや状態(State)を表現できていないことに起因します。
かつて、カート内の数量変更や「あと〇〇円で送料無料」といった動的なロジックをテストするには、ProtoPieを導入するか、React/Vueでプロトタイプコードを組むしかありませんでした。しかし、FigmaのVariables(変数)とConditional Logic(条件分岐)の進化により、デザインツールの枠組みの中で「完全に状態を持つ(Stateful)プロトタイプ」が構築可能になっています。
本稿では、プロダクトの価値を最速で検証するために、FigmaのConditional Logicを応用した「完全インタラクティブなECカート機能」の構築術を徹底解説します。開発現場の生産性を爆上げする実用的な設計設計思想、隠れたショートカット、神プラグイン、そしてコードへ直結するVariables(JSON)の設計規則まで、極限の知見を凝縮してお届けします。
—
1. 条件分岐を用いた高度プロトタイプの限界と可能性
「画面のスパゲッティ化」からの完全脱却
従来のFigmaでは、カートの「空状態」「1点追加」「2点追加」「5,000円以上(送料無料適用)」などの全バリエーションを表現するために、何十通りもの画面フレームを作成し、無数の矢印(プロトタイプリンク)で繋ぐ必要がありました。これが「スパゲッティ・プロトタイプ」です。
Conditional Logicを導入することで、「1つのフレーム(画面)」のまま、ユーザーの操作に応じて内部状態(Variables)を更新し、コンポーネントの表示やテキストを動的に切り替えることが可能になります。
【従来】
[空カート] -> (クリック) -> [1点カート] -> (クリック) -> [2点カート] -> … (画面爆発)
【Conditional Logic導入後】
[1つのカート画面]
└─ ボタン押下 ──> cart_count += 1
└─ ロジック評価 ─> if (total_price >= 5000) { show_free_shipping = true }
限界を見極める:Figmaで「やるべきこと」「やるべきでないこと」
テックリードとして重要なのは、Figmaのプロトタイピングの限界(限界効用)を正しく見極めることです。
- 可能性(得意分野):
- 変数値(数値・文字列・Boolean)の保持と計算(加減乗除)。
- `if / else` による分岐(閾値を超えた際のUI切り替え、バリアント変更)。
- ユーザーテストにおける「非定型な操作」へのリアルタイム追従。
- 限界(不得意分野・コードで書くべき領域):
- 複雑な配列操作(Array.map / filter のような動的なリスト要素の自動生成や削除)。
- 正規表現を用いたバリデーションチェック。
- セッションを跨ぐ複雑なローカルストレージの擬似再現(永続化の限界)。
原則: 「リストの要素増減ロジック」は最大3〜5個程度のコンポーネントバリエーション(またはBooleanによる表示制御)で割り切り、「金額計算」「閾値フラグ」「UIの動的変容」にリソースを集中させるのが最も投資対効果(ROI)が高いアプローチです。
—
2. カート内の商品数・合計金額に応じた動的な表示切り替えの実装手順
ここからは、実際に「商品追加」「数量変更」「送料無料メーターの動的更新」を備えたECカートの実装手順を解説します。
ステップ1:ローカル変数(Variables)の定義
まず、Figmaの「Local Variables」を開き、`Cart` というコレクションを作成して以下の変数を定義します。
| 変数名 (Variable Name) | 型 (Type) | 初期値 | 役割 |
| :— | :— | :— | :— |
| `cart/item_count` | Number | `0` | カート内の合計商品数 |
| `cart/unit_price` | Number | `1200` | 商品単価(1点あたり1,200円) |
| `cart/total_price` | Number | `0` | 合計金額(`item_count unit_price`) |
| `cart/free_shipping_limit`| Number | `5000` | 送料無料の閾値(5,000円) |
| `cart/amount_to_free` | Number | `5000` | 送料無料まであといくらか |
| `cart/is_free_shipping` | Boolean | `false` | 送料無料が適用されているか |
—
ステップ2:ロジックの構築(「カートに追加」ボタン)
「カートに追加」ボタンの `On click` イベントに、複数のアクションと Conditional Logic をセットします。
// 1. カート数のインクリメント
Set variable `cart/item_count` to `cart/item_count + 1`
// 2. 合計金額の再計算
Set variable `cart/total_price` to `cart/item_count cart/unit_price`
// 3. 送料無料までの差額計算
Set variable `cart/amount_to_free` to `cart/free_shipping_limit – cart/total_price`
// 4. 条件分岐によるフラグ更新
Conditional:
if (cart/total_price >= cart/free_shipping_limit)
Set variable `cart/is_free_shipping` to true
else
Set variable `cart/is_free_shipping` to false
> Expert Tip: アクションの順序が極めて重要です。`item_count` を更新した後に `total_price` を計算しなければ、1ステップ前の古いの値で計算が行われてしまいます。
—
ステップ3:UI要素とVariablesのバインディング
作成した変数をキャンバス上のコンポーネントに接続します。
1. バッジ(商品数): カートアイコンのバッジテキストを選択し、Textプロパティに `cart/item_count` をバインド。さらに、`cart/item_count == 0` の場合は非表示にするため、Layerの可視性に Conditional Logic または Variant 切り替えを接続。
2. あと〇〇円で送料無料プログレスバー:
- テキスト要素「あと ¥`cart/amount_to_free` で送料無料!」の動的部分に変数を挿入。
- `cart/is_free_shipping == true` になった場合、テキストを「送料無料が適用されました!」にコンポーネントバリアント(またはLayerのBoolean)で切り替え。
3. プログレスバーの幅(Dynamic Width):
- プログレスバーのインナーFillフレームを選択し、幅(Width)プロパティに直接変数をバインドすることはFigmaの仕様上現在難しいため、「0%, 25%, 50%, 75%, 100%」の5つのバリアントを持つコンポーネントを用意。
- `cart/total_price` の値に応じてバリアントを切り替えるConditionalを追加します。
Conditional (プログレスバー切り替え):
if (cart/total_price == 0) -> Variant: “0%”
else if (cart/total_price < 2500) -> Variant: “25%”
else if (cart/total_price < 5000) -> Variant: “75%”
else -> Variant: “100%”
—
3. ユーザーテストで威力を発揮する「リアル挙動再現」の高度テクニック
ユーザーテストにおいて、プロトタイプが「作り物」だとバレた瞬間に、被験者の思考回路は「実際の買い物」から「テストの操作」へと冷めてしまいます。リアルな挙動を再現するための3つのプロテクニックを紹介します。
テクニック1:ゼロ以下を防ぐ境界値ガード(Boundary Guard)
マイナスボタンを押した際、数量がマイナス値(`-1`)や金額が負の値になるのを防ぐため、必ずネストされた Conditional Logic を組みます。
On click (マイナスボタン):
Conditional:
if (cart/item_count > 0)
Set variable `cart/item_count` to `cart/item_count – 1`
Set variable `cart/total_price` to `cart/item_count cart/unit_price`
// (以下、送料無料計算ロジック)
else
// 0の場合は何もしない、または「カートは空です」トーストを表示
テクニック2:擬似Delayによる非同期フィードバックの演出
「カートに追加」を押した直後、即座に数値が変わるのではなく、ネットワーク通信を再現するために `After delay` を組み合わせたトースト通知を実装します。
1. ボタンクリックで `is_loading` 変数を `true` に(ローディングインジケータ表示)。
2. `Set timeout` 的な挙動として、ローディングアニメーションを持つコンポーネント側の `After delay (300ms)` アクションで実データ(`cart/item_count` 等)を書き換え、`is_loading` を `false` に戻す。
このわずか300msの遅延が、ユーザーテストにおいて「実際のアプリを操作している」という強烈な錯覚を生み出します。
—
4. 開発速度を極限まで高めるキーボードショートカット&神プラグイン
プロトタイピングのロジック構築は、作業効率との戦いです。マウント操作を減らし、脳の思考速度でFigmaを操作するための厳選ナレッジです。
隠れた神キーボードショートカット
- `Shift + Space` : インラインプロトタイププレビュー(別ウィンドウを開かず、作業中のキャンバス上で即座に動作確認。爆速検証の必須ショートカット)。
- `Option + 1` / `Option + 2` : Layersパネル / Assetsパネルの瞬時切り替え(コンポーネント配置の高速化)。
- `Shift + V` : Variablesダイアログの即時呼び出し(ロジック構築中の変数確認・追加)。
- `Option + Cmd + K` : コンポーネント化(ロジックを組む最小単位を即座に作成)。
必須の「神」プラグイン3選
1. Variables Import/Export (by Figma)
- JSON形式でVariablesを一括エクスポート/インポート可能。コード側(Design Tokens)との完全同期や、大規模な変数セットの一括定義に不可欠。
2. Instance Switcher / Variant Matrix
- Conditional Logicで大量のバリアント切り替えを定義する際、コンポーネント構造をマトリクス状に可視化して検証漏れを防ぐ。
3. Prototyper
- 複雑なプロトタイプアクション(変数割り当てや条件分岐)のコピー&ペースト、複数エレメントへの一括適用を可能にする開発者向けユーティリティ。
—
5. チーム開発における設定の共有化ルールとJSON構成例
FigmaのVariablesやLogicは、設計規則(命名規則)がないと一瞬でカオス化します。フロントエンドのデータ構造(Redux, Zustand, Vuexなど)と1:1でマッピングできる設計ルールをチームで定義しましょう。
命名規則(Variable Naming Conventions)
変数名はスラッシュ(`/`)で区切り、Figma内で自動的にグループ化(フォルダ化)される仕組みを利用します。
- `コンテキスト / データ型 / 識別子`
- 例: `cart/num/item_count`
- 例: `cart/bool/is_free_shipping`
- 例: `checkout/str/coupon_code`
実用設定ファイル:Design Tokens & Variable Schema (JSON)
以下は、FigmaのVariablesからエクスポートされ、フロントエンド(React/TypeScript等)でそのまま状態管理(State Management)やStyle Dictionaryとして利用可能なデータ構造のベストプラクティス例です。
{
“$schema”: “https://design-tokens.github.io/community-group/format/”,
“cart_state_schema”: {
“description”: “ECカートプロトタイプおよびフロントエンド状態管理のための設計定義”,
“version”: “1.2.0”,
“variables”: {
“cart/item_count”: {
“$type”: “number”,
“$value”: 0,
“description”: “カート内の総アイテム数”,
“validation”: {
“min”: 0,
“max”: 99
}
},
“cart/unit_price”: {
“$type”: “number”,
“$value”: 1200,
“description”: “対象商品の単価(JPY)”
},
“cart/total_price”: {
“$type”: “number”,
“$value”: 0,
“description”: “計算値: item_count unit_price”,
“derived”: true,
“expression”: “cart/item_count cart/unit_price”
},
“cart/free_shipping_limit”: {
“$type”: “number”,
“$value”: 5000,
“description”: “送料無料が適用される閾値金額”
},
“cart/amount_to_free”: {
“$type”: “number”,
“$value”: 5000,
“description”: “計算値: max(0, free_shipping_limit – total_price)”,
“derived”: true
},
“cart/is_free_shipping”: {
“$type”: “boolean”,
“$value”: false,
“description”: “送料無料フラグ: total_price >= free_shipping_limit”
}
},
“component_variant_mapping”: {
“FreeShippingMeter”: {
“state_binding”: “cart/is_free_shipping”,
“variants”: {
“true”: “Applied”,
“false”: “Progressing”
}
}
}
}
}
このJSON構造をチームのドキュメント(StorybookやNotion)に配備し、デザイナーとエンジニアが「この変数はフロントエンドのどの `useState` / `Store` に対応するか」を合意した上でプロトタイプを構築します。
—
結論:プロトタイプは「絵」ではなく「動く仕様書」へ
Figmaの Conditional Logic を使いこなすことは、単にプロトタイプをリアルにすることにとどまりません。
デザイナーがLogicを組むプロセスそのものが、「例外処理(エッジケース)の思考」「状態遷移の整理」「エンジニアリングへの歩み寄り」そのものです。これにより、「デザインはできあがったが、仕様の抜け漏れが多くて実装時に手戻りが発生する」というWebプロダクト開発最大の課題が根本から解決されます。
画面の紙芝居を今すぐやめ、状態を持った「生きた仕様書」としてプロトタイプを構築しましょう。それこそが、シームレスな開発者体験(DX)と最高のユーザー体験(UX)を両立させる唯一の道です。