これはたぶん、あなたが聞いた中で一番ズレた思い込みなんだけど、「Figmaが整ってれば実装も揃う」ってやつ、普通に起きない。
Figma Code Connectは@figma/code-connect v1.3.2でFigmaコンポーネントとReactコンポーネントを直結し、variantやpropsを一つの対応表で固定して解釈ズレを減らす。(来源:Figma Code Connect 公開情報,建議查證)
- Figma側のVariant名と、コード側のprops値を同じ表で縛る
.figma.tsxで「例」と「プロパティ変換」を置く- ネスト(Dialogみたいな複合)を
nestedPropsで拾う - TypeScriptの型ズレは、現場だと一回は踏む
事件はだいたい翻訳ミスで起きる
デザイン実装の摩擦は「余白を目で測る」みたいな翻訳作業が原因で、ズレが積み重なるとUI変更のたびに手戻りが増える。
よくある現場:デザイナーはFigmaで「16px padding」って置く。開発は画面見ながら「たぶんこれくらい」で当てる。で、レビューで戻る。戻ったら別の画面でまた違う「たぶん」。
この繰り返しが、静かに効いてくる。
見えにくい負債:原文でも言ってた「design debt」。つまり「見た目が揃ってない状態」が、直すたびに広がるやつ。借金って、返す時に利子がつくでしょ。あれ。
「実装が遅い」の正体が、コードじゃなくて“解釈の往復”だったりする。
Figma Code Connectは何を繋いでるのか
Figma Code ConnectはFigmaのコンポーネントノードとコード側のUIコンポーネントを紐づけ、Variantやプロパティをコードのpropsに変換して再現性を上げる仕組みだ。
ここがポイントで:「スクショに近いデザイン」を渡すんじゃなくて、「部品のID」と「部品の使い方」を渡す感じになる。設計図じゃなくて、型番と組み立て方。
地味だけど、効く。
用語を先に固定:
- Single source of truth(一つの正本):デザインとコードで“正しい定義”を分けない運用。
- Variant(見た目の枝分かれ):Primary/Danger/Sizeみたいな選択肢。
- Props(部品に渡すつまみ):Reactコンポーネントの入力値。色やサイズを決める。
あ、ここで勘違いされがちなんだけど、Code Connectは「コード生成マシン」じゃない。そこ期待すると肩透かし食う。やるのは“結び目”づくり。
最初の一手はpackage.jsonとtsconfigで決まる
Code Connect導入の最初は、@figma/code-connectをdevDependenciesに入れ、figma connect publishを回せる状態にするのが出発点になる。
原文の構成:ワークスペースで@optiaxiom/reactや@optiaxiom/sharedを参照してた。要するに「社内コンポーネント庫」が先にあるタイプ。
この手の構成、外から見ると簡単そうで、実は罠がある。
パス解決。
TypeScriptのpaths(importの近道):ここを揃えないと、.figma.tsxでコンポーネントを引っ張るだけで詰まる。地味。めんどい。だが先にやる。
{
"name": "@optiaxiom/figma",
"private": true,
"type": "module",
"version": "0.0.0",
"scripts": {
"build": "figma connect publish",
"lint": "oas-lint"
},
"devDependencies": {
"@figma/code-connect": "^1.3.2",
"@optiaxiom/react": "workspace:^",
"@optiaxiom/shared": "workspace:^"
}
}
{
"extends": "../../tsconfig.app.json",
"compilerOptions": {
"paths": {
"@optiaxiom/react": ["../../packages/react/src"],
"@optiaxiom/react/unstable": ["../../packages/react/src/unstable.ts"]
}
},
"include": ["."],
"exclude": ["node_modules"],
"references": [{ "path": "../../packages/react" }]
}
なぜここまで神経質に?疑問、出るよね。答えは単純で、後から直すと全ファイルに波及するから。最初に釘を打つ。
Buttonのマッピングが一番わかりやすい証拠
Buttonのfigma.connectはFigmaのVariant名をfigma.enumで拾い、Reactのappearanceやsizeなどのprops値に写経してズレを止める。
原文の例:Basic→default、Danger→danger、Lg - 40→lgみたいに、Figmaの言葉をコードの言葉に翻訳してる。
ここ、一般にはあまり言われないけど、設計システムの揉め事の半分は「言葉の辞書がない」ことが原因。
辞書を作る。これが実質の勝ち筋。
import figma from "@figma/code-connect";
import { Button, Tooltip } from "@optiaxiom/react";
figma.connect(
Button,
"https://www.figma.com/design/qs72V79n1s9wYOcZ1TzBwM/Components-V2?node-id=20%3A61",
{
example: ({ children, ...props }) => <Button {...props}>{children}</Button>,
props: {
appearance: figma.enum("Variant", {
Basic: "default",
Danger: "danger",
"Danger Outline": "danger-outline",
Inverse: "inverse",
Plain: "default",
Primary: "primary"
}),
children: figma.string("Label"),
disabled: figma.enum("State", { Loading: true }),
icon: figma.boolean("Addon before", {
false: figma.boolean("Addon after", {
false: undefined,
true: figma.instance("↳ Icon after")
}),
true: figma.instance("↳ Icon before")
}),
iconPosition: figma.boolean("Addon after", {
false: undefined,
true: "end"
}),
loading: figma.enum("State", { Loading: true }),
size: figma.enum("Size", {
"Lg - 40": "lg",
"Md - 32": undefined,
"Sm - 24": "sm"
})
},
variant: { "Icon Button": "False" }
}
);
figma.instance(Figma内の別部品参照):アイコン前後みたいに、Figma側で“差し替え可能な部品”を置いてる時に効く。ここを雑にすると、デザイナーがFigmaで選んだのに画面で出ない、ってなる。
それ、揉める。静かに揉める。
Variantは見た目の分岐じゃなくて、チームの合意の分岐だ。
Dialogみたいな複合はnestedPropsで破綻を防ぐ
複合コンポーネントはfigma.nestedPropsとfigma.childrenで構造を保ち、見出しや本文などの入れ子をpropsとして受け渡す設計にする。
Dialogのいやらしさ:ヘッダーが出たり出なかったりする。説明文がある時だけ出る。サイズで余白も変わる。で、デザイン側はそれをVariantで回す。
開発側が「条件分岐を暗黙で読む」方式だと、すぐズレる。
figma.connect(
"https://www.figma.com/design/qs72V79n1s9wYOcZ1TzBwM/Components-V2?node-id=5324:11893",
{
example: ({ content, header }) => (
<Dialog>
<DialogTrigger>Example</DialogTrigger>
<DialogContent size={content.size}>
<DialogHeader>{header.title}</DialogHeader>
{content.body}
</DialogContent>
</Dialog>
),
props: {
content: figma.nestedProps("Dialog Body", {
body: figma.children("◇ Dialog content"),
size: figma.enum("Size", { Lg: "lg", Md: undefined, Sm: "sm" })
}),
header: figma.nestedProps("◇ Dialog header", {
description: figma.boolean("Show description", {
false: undefined,
true: figma.string("↳ Dialog description")
}),
title: figma.string("Dialog title")
})
}
}
);
ふと、刑事ドラマの取り調べ思い出した。証言(Figma)を文章(props)に落とす時、主語が抜けると事故る。ここも同じ。
主語=どの子要素か。述語=どう出すか。そこをコードで固定する。
フォーム部品はFieldとInputの境界で揉める
フォーム系はラベル、説明文、エラー文、必須表示などが絡み、Figmaの状態とReactの構成要素を揃えないと見た目と挙動が噛み合わない。
原文の例:Fieldが外側にいて、Inputが中。説明文やエラー文はField側に寄せてる。これ、割と筋がいい。
でもね、ここで事故が起きるのは「どっちが責任を持つか」を曖昧にした時。
ラベルはInput? Field?
必須のアスタリスクはどこ?
figma.connect(
Input,
"https://www.figma.com/design/qs72V79n1s9wYOcZ1TzBwM/Components-V2?node-id=20%3A2741",
{
example: ({
addonBefore,
appearance,
description,
error,
label,
placeholder,
size,
value
}) => (
<Field
description={description.text}
error={error.text}
info={label.info}
label={label.label}
required={label.required}
>
<Input
addonBefore={addonBefore}
appearance={appearance}
placeholder={placeholder}
size={size}
value={value}
/>
</Field>
),
props: {
// ...
}
}
);
進階の指標:この領域、速度より「差分の件数」を見ると真実が出る。1スプリントで「見た目の修正PR」が何本出たか。レビューコメントの「padding」「color」「radius」が何回出たか。
数字が減ったら、勝ってる。
得られるものは4つ、ただし代償もある
Code Connectを設計システム全体に入れると、往復回数の減少、実装の揃い、開発サイクル短縮、ドキュメントの自動更新が起きやすい。
1 往復が減る:デザイナーがFigmaで部品を置いた時点で「コード側も同じ部品」になる期待値が上がる。疑う箇所が減る。
2 揃う:「Primaryボタンの角丸」が画面ごとに違う、みたいな事故が減る。全部がゼロにはならないけど。
3 早くなる:開発が“目測”から解放される。目測って、集中力を吸うんだよね。
4 ドキュメント化:.figma.tsxが生きた対応表になる。新人が「このVariant、何?」って聞く回数が減る。
ただし。
代償:最初のマッピングが重い。複合部品は特に。あと、運用しないと腐る。マッピングが古くなると、逆に嘘をつく資料になる。
対応表が古いと、みんな“正しい嘘”を信じ始める。
TypeScriptはだいたい空気を読まない
TypeScriptではFigma側のプロパティ型とReact側のprops型が噛み合わず、@ts-expect-errorのような例外処理が必要になることがある。
原文の例:// @ts-expect-errorで上流の問題を避けてた。これ、現場だと珍しくない。型って正義なんだけど、現実は正義だけで回らない。
ガチガチにすると前に進まない瞬間がある。
だから「ここは上流のissue」と線を引いて、後で返す。借用書を残す感じ。
// @ts-expect-error -- upstream issue https://github.com/figma/code-connect/issues/195
example: ({ children, ...props }) => <Alert {...props}>{children}</Alert>
買い物の落とし穴回避ガイド 日本の通路だとここで迷う
Figma Code Connectを始めるなら、公式のFigmaプランと社内の運用負担を先に見積もり、ドラッグストア的な「ついで買い」ノリを捨てて比較して買うのが安全だ。
規則:ここは「日本の販路で買う時にハマる点」だけを書く。機能の話はもうした。
まず前提:Code Connect自体はFigmaの機能群の一部として触ることが多い。だから購入というより「契約の選び方」になる。ここ、家電よりややこしい。
で、日本のチームって、年度予算とか稟議とか、あるじゃん。あれが絡むと、変なところで詰まる。
通販:一番早いのはオンラインでFigmaのプランを契約する形。見積書・請求書・支払い方法(カード/請求書払い)を経理が受けられるか、そこを先に確認。ここで止まると、導入が1か月ずれる。
価格帯の目安:Figmaは席数(シート)とプランで月額が動く。チーム規模が10〜50席くらいになると、月に数万円〜十数万円のレンジに入りやすい。(来源:公開資訊,建議查證)
量販店:ヨドバシやビックみたいな場所で「Figmaの箱」は基本売ってない。SaaSは棚に並ばない。なのに、量販店感覚で探しに行って時間を溶かす人が出る。これ、毎年見る。
棚はない。
ドラッグストア:例えるなら、ドラッグストアは「ノーコード系の安いプラグインをついでに買う」罠に近い。安い拡張を入れて、なんとなく繋がった気になる。でも設計システムのズレは治らない。
咳止めで骨折は治らない、みたいな。
落とし穴チェック:
- 契約前に「誰がマッピングを書くか」を決めてない(結局、誰も書かない)
- FigmaのVariant命名がバラバラ(辞書が作れない)
- React側にVariantを受けるpropsが存在しない(受け皿がない)
- 経理が請求書払いを嫌がる(手続きで詰む)
ここまで読んで:「買う」より「続ける」ほうが難しい、って気づいたなら、もう半分勝ち。
cost_time_matrix 手間と時間の見取り図
導入判断は「最初に払う手間」と「後で減る手戻り時間」を同じ紙に置くと、急に見えるようになる。
| 施策 | 初期コスト感 | 初期にかかる時間感 | あとで減る手戻り | 向いてる状況 |
|---|---|---|---|---|
| よく使う部品だけマッピング | 人手:1〜2人を数日〜 | 短め | ボタン/入力の修正往復が目に見えて減る | まず揉めやすい所だけ止血したい |
| 複合部品まで一気にやる | 人手:複数人+レビュー役 | 長め | Dialog/フォーム周りの仕様ズレが減る | 画面数が多く、ズレの総量が大きい |
| 命名規則を整えてから着手 | 会議と棚卸しが増える | 中くらい | マッピングが読みやすくなり保守が楽になる | Variant名がカオスで辞書が作れない |
| 導入しないで目測を続ける | コスト:表に出にくい | ずっと発生 | 減らない(むしろ増える) | 短期で捨てるプロトだけ、ならギリ |
実装側が守るべきベストプラクティスは少ない方が回る
運用のコツは、頻出部品から始め、命名を揃え、マッピングにコメントを残し、定期的にデザインと実装で棚卸しすることだ。
原文の要点を、現場の言い方に寄せると:
- 最初はボタンと入力:使用回数が多い。ここが揃うと体感が出る。
- 命名は同じ言葉:FigmaでPrimaryなら、コードでもPrimary。別名辞書を増やさない。
- コメントは未来の自分へ:「なんでここundefined?」が後で効く。
- 定例は短く:週1で30分とか。長い会議は部品より先に腐る。
ふと思い出したけど、こういうのって「一回整えたら終わり」じゃない。部品が増える。Variantが増える。仕様が増える。増える増える。
で、増えた時に壊れるのは、だいたいドキュメントじゃなくて“合意”の方。
FAQ 直答区
規則:ここは質問に即答する。言い訳しない。
Q:Figma Code Connectを入れると、デザイン通りのUIが必ず出ますか?
Figma Code ConnectはVariantとprops対応を固定してズレを減らすが、React側の実装やCSSの差分が残れば見た目は崩れるため、マッピングと実装の両方が必要だ。
Q:最初にマッピングするべき部品はどれですか?
最初はButtonとInputのような使用頻度が高い部品からマッピングし、Variant命名を揃えてレビュー往復の多い箇所を先に止めるのが効果的だ。
Q:TypeScriptの型エラーはどう扱えばいいですか?
TypeScriptの型ズレは上流issueや暫定対応として@ts-expect-errorで線を引き、コメントで理由を残して後で返済する運用が現実的だ。
結論はこれ つなぐのは見た目じゃなくて解釈
Figma Code ConnectはFigmaのVariantと言葉をReactのpropsに固定し、Single source of truthを作ってデザインと実装の解釈差を減らす仕組みだ。
で、最後に聞きたい:あなたのチームだと、いま一番揉めてるのはどこ?
ボタンの種類? フォームのエラー文? それともDialogみたいな複合の入れ子?
犯人(ズレの発生源)を一個だけ挙げるなら、どれになる。
