figma-code-connect について
figma-code-connect は、公開済みの Figma コンポーネントをコードスニペットに結び付ける parserless Code Connect テンプレートを作成するスキルです。コンポーネントの検出、プロパティの対応付け、`.figma.ts` ファイルの作成を案内します。
主な機能
- 01`figma.code` による `.figma.ts` テンプレート作成
- 02未マッピングの公開済みコンポーネントの検出
- 03Figma プロパティとコードプロパティの対応付け
- 04バリアント、スロット、インスタンススワップへの対応
活用シーン
- 01公開済み Figma コンポーネントをコードコンポーネントに接続
- 02Figma URL で選択したコンポーネントのテンプレート生成
MCP 対応
Figma MCP サーバーへの接続が必要です。`get_code_connect_suggestions` と `get_context_for_code_connect` を使い、コンポーネントとそのプロパティを調べます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ figma/ mcp-server-guide --skill figma-code-connectインストール後、Claude Code で/figma-code-connectを入力して読み込まれたか確認します。
同梱ファイルreferences/advanced-patterns.mdreferences/api.md
詳細
Code Connect
概要
Figma コンポーネントをコードスニペットに対応付ける Code Connect テンプレートファイル(.figma.ts)を作成します。Figma の URL を受け取ったら、以下の手順に従ってテンプレートを作成します。
作成するのは
.figma.tsテンプレートファイルのみです。.figma.tsxは作成しないでください。 このスキルで生成するのは パーサーレスのテンプレート です。つまり、デフォルトエクスポートでfigma.code`...`タグ付きテンプレートを使用する.figma.tsファイルです。.figma.tsxファイルは作成せず、figma.connect()も使用しないでください。これは別の パーサーベース Code Connect 形式(別の方法で公開されます)であり、このスキルで作成する成果物としては 誤り です。.figma.tsxとして作成された出力は、そのまま拒否されます。コンポーネントに.figma.tsxがすでにある場合は、そのまま残し、隣に.figma.tsテンプレートを追加してください。知識のあるモデルは、記憶にあるより馴染み深い.figma.tsx/figma.connect()パターンを使いたくなるかもしれませんが、それは避けてください。ここで正しい出力は 常に.figma.ts+figma.codeです。
前提条件
- Figma MCP サーバーに接続している必要があります — 続行する前に、Figma MCP ツール(例:
get_code_connect_suggestions)が利用可能であることを確認してください。利用できない場合は、Figma MCP サーバーを有効にして MCP クライアントを再起動するようユーザーに案内してください。 - コンポーネントは公開済みである必要があります — Code Connect は、Figma チームライブラリに公開されたコンポーネントでのみ機能します。コンポーネントが公開されていない場合は、その旨をユーザーに伝えて終了してください。
- Organization または Enterprise プランが必要です — Code Connect は Free または Professional プランでは利用できません。
- URL に
node-idが含まれている必要があります — Figma の URL にはnode-idクエリパラメーターが必要です。 - TypeScript 型 —
.figma.tsファイルでエディターの自動補完と型チェックを利用するには、@figma/code-connect/figma-typesをtsconfig.jsonのtypesに追加する必要があります。{ "compilerOptions": { "types": ["@figma/code-connect/figma-types"] } }
ステップ 1:Figma URL を解析する
URL から fileKey と nodeId を抽出します。
| URL 形式 | fileKey | nodeId |
|---|---|---|
figma.com/design/:fileKey/:name?node-id=X-Y | :fileKey | X-Y → X:Y |
figma.com/file/:fileKey/:name?node-id=X-Y | :fileKey | X-Y → X:Y |
figma.com/design/:fileKey/branch/:branchKey/:name | :branchKey を使用 | node-id パラメーターから取得 |
必ず nodeId のハイフンをコロンに変換してください。1234-5678 → 1234:5678。
例:
入力:https://www.figma.com/design/QiEF6w564ggoW8ftcLvdcu/MyDesignSystem?node-id=4185-3778
fileKey=QiEF6w564ggoW8ftcLvdcunodeId=4185-3778→4185:3778
ステップ 2:未マッピングのコンポーネントを探す
ユーザーが指定する URL は、コンポーネントセットや単独のコンポーネントではなく、フレーム、インスタンス、またはバリアントを指している場合があります。次の引数を指定して MCP ツール get_code_connect_suggestions を呼び出します。
fileKey— ステップ 1 で取得した値nodeId— ステップ 1 で取得した値(コロン形式)excludeMappingPrompt—true(未マッピングのコンポーネントの簡易一覧を返します)
このツールは、選択範囲に含まれる公開済みコンポーネントのうち、まだ Code Connect マッピングがないものを特定します。
応答の処理:
- 「No published components found in this selection」 — ノードに公開済みコンポーネントが含まれていません。まず Figma のチームライブラリにコンポーネントを公開する必要があることをユーザーに伝えて終了してください。
- 「All component instances in this selection are already connected to code via Code Connect」 — すべてマッピング済みです。その旨をユーザーに伝えて終了してください。
- コンポーネント一覧を含む通常の応答 — 返された各コンポーネントの
mainComponentNodeIdを抽出します。以降のすべての手順では、元の URL のノード ID ではなく、解決済みのこれらのノード ID を使用してください。複数のコンポーネントが返された場合(例:ユーザーが複数の異なるコンポーネントインスタンスを含むフレームを選択した場合)は、それぞれについてステップ 3~6 を繰り返します。
ステップ 3:コンポーネントのプロパティを取得する
MCP ツール get_context_for_code_connect を次の内容で呼び出します。
fileKey— ステップ 1 で取得した値nodeId— ステップ 2 で解決したmainComponentNodeIdclientFrameworks—figma.config.jsonのparserフィールドから特定します(例:"react"→["react"])clientLanguages— プロジェクトのファイル拡張子から推測します(例:TypeScript プロジェクト →["typescript"]、JavaScript →["javascript"])
複数のコンポーネントがある場合は、ノード ID ごとにツールを 1 回呼び出します。
レスポンスには、Figma コンポーネントのプロパティ定義が含まれています。各プロパティの名前と型を確認してください。
- TEXT — テキストコンテンツ(ラベル、タイトル、プレースホルダー)
- BOOLEAN — 切り替え項目(アイコンの表示/非表示、無効状態)
- VARIANT — 列挙オプション(サイズ、バリアント、状態)
- INSTANCE_SWAP — 特定のコンポーネントに関連付けられた、入れ替え可能なネストされたインスタンス(アイコン、アバター)
- SLOT — 柔軟なコンテンツ領域(自由形式のレイアウト、複数の子要素)。テンプレートでは
getSlot()を使用します(INSTANCE_SWAP とは異なります)。
このプロパティ一覧を保存します。ステップ 5 でテンプレートを作成する際に使用します。
ステップ 4:コードコンポーネントを特定する
ユーザーが接続するコードコンポーネントを指定していない場合は、次の手順を実行します。
figma.config.jsonのpathsとimportPathsを確認し、コンポーネントの配置場所を特定します。- コードベースで、Figma コンポーネント名に一致するコンポーネントを検索します。
figma.config.jsonにパスが指定されていない場合は、一般的なディレクトリ(src/components/、components/、lib/ui/、app/components/)を確認します。 - 候補ファイルを読み込み、props インターフェイスをステップ 3 の Figma プロパティと比較します。一致するバリアント型、サイズオプション、ブール値フラグ、スロット props を探します。
- 複数の候補が一致する場合は、props インターフェイスが最もよく一致するものを選び、その理由をユーザーに説明します。
- 一致するものが見つからない場合は、最も近い候補を 2 つ提示し、ユーザーに確認するか、正しいパスを指定するよう依頼します。
ステップ 5 に進む前に、ユーザーに確認します。見つかったコードコンポーネント、その配置場所、そして一致すると判断した理由(props の対応関係、名前、用途)を提示します。
インポートパスのエイリアスを確認するため、figma.config.json を読み込みます。importPaths セクションはグロブパターンをインポート指定子に対応付け、paths セクションはそれらの指定子をディレクトリに対応付けます。
ステップ 5 で Figma のプロパティをコードの props にマッピングする方法を把握できるよう、コードコンポーネントのソースを読み、props インターフェイスを確認します。
ステップ 5:テンプレートファイル(.figma.ts)を作成する
ファイルの配置場所
既存の Code Connect ファイルと同じ場所にファイルを配置します。適切なディレクトリを確認するには、figma.config.json の include パターンを確認します。ファイル名は ComponentName.figma.ts とします。ComponentName.figma.tsx にしてはいけません。 .figma.tsx 拡張子はパーサーベースの形式です。新たに作成したり、既存のファイルを変更したりしないでください。
テンプレートの構造
すべてのテンプレートファイルは、次の構造に従います。
// url=https://www.figma.com/file/{fileKey}/{fileName}?node-id={nodeId}
// source={path to code component from Step 4}
// component={code component name from Step 4}
import figma from 'figma'
const instance = figma.selectedInstance
// Extract properties from the Figma component (see property mapping below)
// ...
export default {
example: figma.code`<Component ... />`, // Required: code snippet
imports: ['import { Component } from "..."'], // Optional: import statements
id: 'component-name', // Required: unique identifier
metadata: { // Optional
nestable: true, // true = inline in parent, false = show as pill
props: {} // data accessible to parent templates
}
}
プロパティのマッピング
ステップ 3 のプロパティ一覧を使って値を抽出します。Figma の各プロパティタイプには、対応するメソッドを使用します。
| Figma プロパティタイプ | テンプレートメソッド | 使用する場面 |
|---|---|---|
| TEXT | instance.getString('Name') | ラベル、タイトル、プレースホルダーテキスト |
| BOOLEAN | instance.getBoolean('Name', { true: ..., false: ... }) | 表示の切り替え、条件付きプロパティ |
| VARIANT | instance.getEnum('Name', { 'FigmaVal': 'codeVal' }) | サイズ、バリアント、状態を表す列挙値 |
| INSTANCE_SWAP | instance.getInstanceSwap('Name') | 固定コンポーネントスロットの差し替え対象インスタンス(その後、hasCodeConnect() / executeTemplate() を使用) — 下記の SLOT プロパティと混同しないでください |
| SLOT | instance.getSlot('Name') | Figma のプロパティタイプが SLOT の場合に限る、自由形式のスロットコンテンツ |
| (子レイヤー) | instance.findInstance('LayerName') | プロパティのない、名前付きの子インスタンス |
| (テキストレイヤー) | instance.findText('LayerName') → .textContent | 名前付きレイヤーのテキストコンテンツ |
TEXT — 文字列値を直接取得します。
const label = instance.getString('Label')
VARIANT — Figma の列挙値をコードの値にマッピングします。
const variant = instance.getEnum('Variant', {
'Primary': 'primary',
'Secondary': 'secondary',
})
const size = instance.getEnum('Size', {
'Small': 'sm',
'Medium': 'md',
'Large': 'lg',
})
BOOLEAN — 単純な真偽値、または値へのマッピングに使用します。
// Simple boolean
const disabled = instance.getBoolean('Disabled')
// Mapped to code values (e.g. when the code prop is an enum, not a boolean)
const size = instance.getBoolean('Show Label', { true: 'large', false: 'small' })
有効な対応関係がある場合は、Figma のプロパティをコードのプロパティにマッピングします。 Figma のプロパティとコードのプロパティは、常に 1 対 1 で対応するとは限りません。Figma のプロパティの中には、名前または上記の API メソッドを使って直接マッピングできるものもあれば、対応するコード側のプロパティがないものもあります。対応関係がある場合はマッピングし、該当するものがない場合は、コード側のプロパティを作り出さずに Figma のプロパティを省略してください。コードコンポーネントの Props インターフェースに存在しない名前の属性は、絶対に出力しないでください。
バリアントの網羅的な処理
VARIANT プロパティに複数の値がある場合、getEnum のマッピングには get_context_for_code_connect が返すすべての値を必ず含めてください。値を省略しないでください。マッピングされていない値は警告なく undefined を返し、出力が壊れる原因になります。
// WRONG — omits 'Warning', which will render as undefined
const status = instance.getEnum('Status', {
'Success': 'success',
'Error': 'error',
})
// CORRECT — every value is mapped
const status = instance.getEnum('Status', {
'Success': 'success',
'Error': 'error',
'Warning': 'warning',
'Info': 'info',
})
2 つ以上の VARIANT プロパティの組み合わせによってコードの出力が変わる場合は、すべての条件分岐を生成します。たとえば、2 つのバリアントがそれぞれ 2 つの値を持つ場合、分岐は 4 つになります。
const type = instance.getEnum('Type', { 'Filled': 'filled', 'Outlined': 'outlined' })
const status = instance.getEnum('Status', { 'Success': 'success', 'Error': 'error' })
let colorClass
if (type === 'filled' && status === 'success') {
colorClass = 'bg-green-500 text-white'
} else if (type === 'filled' && status === 'error') {
colorClass = 'bg-red-500 text-white'
} else if (type === 'outlined' && status === 'success') {
colorClass = 'bg-transparent border-green-500'
} else if (type === 'outlined' && status === 'error') {
colorClass = 'bg-transparent border-red-500'
}
組み合わせによって同じ出力が繰り返される場合(たとえば、Size によってスニペットの構造は変わらず、プロパティとして渡されるだけの場合)は、各バリアントに対して単一の getEnum マッピングを使えば十分です。直積の分岐は必要ありません。
INSTANCE_SWAP — 差し替え可能なコンポーネントインスタンスにアクセスします。
const icon = instance.getInstanceSwap('Icon')
let iconCode
if (icon && icon.type === 'INSTANCE') {
iconCode = icon.executeTemplate().example
}
SLOT — getSlot(propName) が有効なのは、ステップ 3 で報告された Figma コンポーネントプロパティのタイプが SLOT の場合に限ります。INSTANCE_SWAP プロパティには getSlot() を使用しないでください(これらには getInstanceSwap() を使用します)。スロットはコンポーネント定義内で明示された「コンテンツ領域」であり、一般的なネストされたインスタンスではありません。
- シグネチャ:
getSlot(propName: string): ResultSection[] | undefined
// Figma property "Content" must be type SLOT in component properties
const content = instance.getSlot('Content')
export default {
example: figma.code`<Card>${content}</Card>`,
// ...
}
タグ付きテンプレートでの補間
タグ付きテンプレートで値を補間する場合は、適切な囲み方を使用します。
- 文字列値(
getString、getEnum、textContent):引用符で囲みます →variant="${variant}" - インスタンス/セクションの値(
executeTemplate().example):波括弧で囲みます →icon={${iconCode}} - スロットセクション(
getSlot()の結果 —ResultSection[] | undefined):figma.code`...`内に直接補間します(ネストされたスニペットセクションと同じ形式)。例:figma.code`<Select>${content}</Select>`— 通常の文字列として扱わないでください - 値だけの BOOLEAN プロパティ:条件式を使います →
${disabled ? 'disabled' : ''}
子孫レイヤーの取得
コンポーネントのプロパティとして公開されていない子要素にアクセスする必要がある場合:
| 方法 | 使用する状況 |
|---|---|
instance.getInstanceSwap('PropName') | Figma のプロパティタイプが INSTANCE_SWAP(固定の差し替えインスタンス)の場合 |
instance.getSlot('PropName') | Figma のプロパティタイプが SLOT(自由形式のコンテンツ領域)の場合 |
instance.findInstance('LayerName') | 子レイヤー名がわかっている場合(コンポーネントプロパティはなし) |
instance.findText('LayerName') → .textContent | 名前付きテキストレイヤーからテキストコンテンツを取得する場合 |
instance.findConnectedInstance('id') | 子の Code Connect id がわかっている場合 |
instance.findConnectedInstances(fn) | フィルターに一致する、接続済みの子要素を複数取得する場合 |
instance.findLayers(fn) | フィルターに一致する任意のレイヤー(テキスト+インスタンス)を取得する場合 |
設定可能なネストされたインスタンス
コンポーネントには、コンポーネントプロパティとして公開されていない(INSTANCE_SWAP がない)ものの、独立して設定可能な独自のバリアント、プロパティ、スワップスロットを持つ子インスタンスが含まれることがあります。これらはハードコードせず、動的に解決する必要があります。
- 子に Code Connect テンプレートがすでにあるか確認します —
get_code_connect_suggestionsを使用するか、プロジェクト内の既存の.figma.tsファイルを確認します。 - テンプレートがない場合は、子のテンプレートを作成します。単体でレンダリングするときも、ネストされているときも正しく表示されるようにします。
findInstance()またはfindConnectedInstance()を使用して子を親から参照し、続けてexecuteTemplate()を呼び出します。
// Parent template — the Badge child isn't a prop, but it's configurable
const badge = instance.findInstance('Status Badge')
let badgeCode
if (badge && badge.type === 'INSTANCE') {
badgeCode = badge.executeTemplate().example
}
export default {
example: figma.code`<Card>${badgeCode}</Card>`,
// ...
}
これはアイコン、バッジ、ラベルなど、単独で設定可能なあらゆるネストされたインスタンスに当てはまります。必ず接続して動的にレンダリングし、コンテンツをハードコードしないでください。
ネストされたコンポーネントの例
複数階層のネストされたコンポーネントや、テンプレート間でのメタデータプロパティの受け渡しについては、advanced-patterns.md を参照してください。
const icon = instance.getInstanceSwap('Icon')
let iconSnippet
if (icon && icon.type === 'INSTANCE') {
iconSnippet = icon.executeTemplate().example
}
export default {
example: figma.code`<Button ${iconSnippet ? figma.code`icon={${iconSnippet}}` : ''}>${label}</Button>`,
// ...
}
条件付きプロパティ
const variant = instance.getEnum('Variant', { 'Primary': 'primary', 'Secondary': 'secondary' })
const disabled = instance.getBoolean('Disabled')
export default {
example: figma.code`
<Button
variant="${variant}"
${disabled ? 'disabled' : ''}
>
${label}
</Button>
`,
// ...
}
ステップ 6:検証
.figma.ts ファイルを読み直し、以下の点を確認します。
- 正しいファイルタイプと形式(最初に確認) — ファイル名が
ComponentName.figma.ts(.figma.tsxではありません)で、デフォルトエクスポートがfigma.code`...`タグ付きテンプレートを使用する、パーサーを使わないテンプレートであること。figma.connect()(パーサーベースの形式)は使用しないでください。.figma.tsxまたはfigma.connect()を記述した場合は破棄し、.figma.tsのfigma.codeテンプレートとして書き直してください。 - プロパティの網羅性 — ステップ 3 のすべての Figma プロパティがテンプレートで扱われていること。欠けているものがあれば指摘し、意図的に省略したかユーザーに確認してください。
- 有効で型が正しいコード — 出力されるコードがすべて有効であり、コードコンポーネントの
Propsインターフェースに対して正しい型になっていること。コンポーネントのプロパティを決して捏造しないでください。Figma のプロパティに対応するコードプロパティがない場合は、作り出すのではなく省略してください。 - 子要素のハードコードがないこと — すべての INSTANCE_SWAP プロパティと子コンポーネントのスロットで、
executeTemplate()とともに動的 API(getInstanceSwap()、findInstance()、findConnectedInstance()など)を使用していることを確認します。スロットにコンポーネントのコンテンツをハードコードしないでください。 - ルールと注意点 — 以下に挙げるよくある間違い(テンプレート結果の文字列連結、不要な
hasCodeConnect()ガード、type === 'INSTANCE'チェックの不足など)がないか確認します。 - 補間のラップ — 文字列(
getString、getEnum、textContent)は引用符で囲み、インスタンス/セクションの値(executeTemplate().example)は波括弧で囲み、スロットのセクション(getSlot)はfigma.code`...`内にスニペットセクションとして補間し、ブール値は条件分岐を使用します。
不明な点があれば、API の詳細については api.md を、複雑なネストについては advanced-patterns.md を参照してください。
インラインクイックリファレンス
instance.* メソッド
| メソッド | シグネチャ | 戻り値 |
|---|---|---|
getString | (propName: string) | string |
getBoolean | (propName: string, mapping?: { true: any, false: any }) | boolean | any |
getEnum | (propName: string, mapping: { [figmaVal]: codeVal }) | any |
getInstanceSwap | (propName: string) | InstanceHandle | null |
getSlot | (propName: string) | ResultSection[] | undefined |
getPropertyValue | (propName: string) | string | boolean |
findInstance | (layerName: string, opts?: SelectorOptions) | InstanceHandle | ErrorHandle |
findText | (layerName: string, opts?: SelectorOptions) | TextHandle | ErrorHandle |
findConnectedInstance | (codeConnectId: string, opts?: SelectorOptions) | InstanceHandle | ErrorHandle |
findConnectedInstances | (selector: (node) => boolean, opts?: SelectorOptions) | InstanceHandle[] |
findLayers | (selector: (node) => boolean, opts?: SelectorOptions) | (InstanceHandle | TextHandle)[] |
InstanceHandle メソッド
| メソッド | 戻り値 |
|---|---|
hasCodeConnect() | boolean |
executeTemplate() | { example: ResultSection[], metadata: Metadata } |
codeConnectId() | string | null |
TextHandle のプロパティ
| プロパティ | 型 |
|---|---|
.textContent | string |
.name | string |
SelectorOptions
{ path?: string[], traverseInstances?: boolean }
traverseInstances: true— 対象が別のネストされたインスタンス内にある場合に必要です。これを指定しないと、findInstance/findTextは現在のインスタンス自身のレイヤーのみを検索し、ネストされたインスタンスの境界で検索を終了します。path: string[]— 複数の子孫が同じレイヤー名を持つ場合に、対象を特定します。対象までのパスに含まれている必要がある親レイヤー名を列挙します。
例:
// Layer hierarchy:
// A > C (instance) > "mychild"
// "mychild" sits inside nested instance C, so plain findInstance returns ErrorHandle.
instance.findInstance('mychild', { traverseInstances: true })
// Layer hierarchy:
// A > C (instance) > "mychild"
// A > D (instance) > "mychild"
// Two "mychild" layers exist — use path to pick the one under C.
instance.findInstance('mychild', { traverseInstances: true, path: ['C'] })
親テンプレートからネストされたインスタンスを参照する場合: 親のコードコンポーネント(ステップ 4)が、ネストされたレイヤー自体をプロパティ値として受け取る場合に限ります(例:<C show={<B />} /> — A が B を C に渡します)。親が単に C を合成し、C が内部で B をレンダリングするだけの場合は、executeTemplate() で C を解決し、C 自身のテンプレートに B を処理させてください。親のレベルで B のレンダリングを重複させないでください。
エクスポート構造
export default {
example: figma.code`...`, // Required: ResultSection[]
id: 'component-name', // Required: string
imports: ['import { X } from "..."'], // Optional: string[]
metadata: { nestable: true, props: {} } // Optional
}
ルールと注意点
-
テンプレートの結果を文字列として連結しないでください。
executeTemplate().exampleはResultSection[]オブジェクトであり、文字列ではありません。+や.join()を使うと[object Object]になります。必ずタグ付きテンプレート内で補間してください:figma.code`${snippet1}${snippet2}` -
hasCodeConnect()のガードは使用しないでください。type === 'INSTANCE'を確認した後は、どのインスタンスに対しても直接executeTemplate()を呼び出します。ランタイムが Code Connect のないインスタンスを自動的に処理します。// WRONG — hasCodeConnect() gate drops non-CC instances if (icon && icon.type === 'INSTANCE' && icon.hasCodeConnect()) { iconCode = icon.executeTemplate().example } // CORRECT — let the runtime handle all instances if (icon && icon.type === 'INSTANCE') { iconCode = icon.executeTemplate().example } -
executeTemplate()を呼び出す前に、type === 'INSTANCE'を確認してください。findInstance()、findConnectedInstance()、findText()は、失敗時にnullではなくErrorHandle(truthy ですが、実際のノードではありません)を返します。クラッシュを防ぐため、必ず型チェックを追加してください:if (child && child.type === 'INSTANCE') { ... } -
スロットにコンポーネントプロパティがある場合は、
findInstance()よりgetInstanceSwap()を優先してください。 アイコンが別の名前に差し替えられるとfindInstance('Star Icon')は動作しなくなりますが、getInstanceSwap('Icon')はスロット内のインスタンスにかかわらず常に動作します。 -
Figma のプロパティタイプが
SLOTの場合にのみ、getSlot()を使用してください。 INSTANCE_SWAP プロパティにはgetInstanceSwap()を使用します(InstanceHandleを返します)。getSlot()はインスタンスではなく、構造化されたスロットセクションを返します。戻り値に対してexecuteTemplate()を呼び出さないでください。 -
プロパティ名は大文字と小文字を区別します。
get_context_for_code_connectが返す名前と完全に一致させる必要があります。 -
複数のテンプレート配列を正しく処理してください。 子要素を反復処理するときは、結果をそれぞれ別の変数に設定して個別に補間してください。
.map().join()は使用しないでください:// Wrong: items.map(n => n.executeTemplate().example).join('\n') // Correct — use separate variables: const child1 = items[0]?.executeTemplate().example const child2 = items[1]?.executeTemplate().example export default { example: figma.code`${child1}${child2}` } -
スロットや子要素の内容をハードコードしないでください。 必ず子インスタンスを動的に解決してください。INSTANCE_SWAP プロパティには
getInstanceSwap()を、直接の子要素にはfindInstance()/findConnectedInstance()を使い、executeTemplate()でレンダリングします。レイヤー名から JSX を構築したり(例:<StarIcon />)、インポートパスを推測したりしないでください。インスタンスに Code Connect がない場合は省略し、ハードコードした代替を追加しないでください。// WRONG — hardcodes the icon from its layer name example: figma.code`<Button icon={<StarIcon />}>Submit</Button>` // CORRECT — resolves dynamically, works for any swapped icon const icon = instance.findInstance('Icon') let iconCode if (icon && icon.type === 'INSTANCE') { iconCode = icon.executeTemplate().example } example: figma.code`<Button${iconCode ? figma.code` icon={${iconCode}}` : ''}>...</Button>` -
すべての Figma プロパティをコードプロパティで表現できるようにしてください。 コードコンポーネントの
Propsインターフェース(ステップ 4 のもの)が、属性名の正式な一覧です。各 Figma プロパティについて、ステップ 5 の API メソッドを使って、直接の名前の一致、値の変換など、適切な表現方法を判断してください。対応するコードプロパティがない場合は省略し、プロパティ名を勝手に作らないでください。
完全な実例
URL:https://figma.com/design/abc123/MyFile?node-id=42-100
ステップ 1: URL を解析します。
fileKey=abc123nodeId=42-100→42:100
ステップ 2: fileKey: "abc123"、nodeId: "42:100"、excludeMappingPrompt: true を指定して get_code_connect_suggestions を呼び出します。
レスポンスには mainComponentNodeId: "42:100" のコンポーネントが 1 つ含まれます。レスポンスが空の場合は停止し、ユーザーに知らせてください。複数のコンポーネントが返された場合は、それぞれについてステップ 3~6 を繰り返します。
ステップ 3: fileKey: "abc123"、nodeId: "42:100"(ステップ 2 の値)、clientFrameworks: ["react"]、clientLanguages: ["typescript"] を指定して get_context_for_code_connect を呼び出します。
レスポンスには次のプロパティが含まれます:
- Label(TEXT)
- Variant(VARIANT):Primary、Secondary
- Size(VARIANT):Small、Medium、Large
- Disabled(BOOLEAN)
- Has Icon(BOOLEAN)
- Icon(INSTANCE_SWAP)
ステップ 4: コードベースを検索し、Button コンポーネントを見つけます。ソースを読んで props を確認します:variant、size、disabled、icon、children。インポートパス:"primitives"。
ステップ 5: src/figma/primitives/Button.figma.ts を作成します:
// url=https://figma.com/design/abc123/MyFile?node-id=42-100
// source=src/components/Button.tsx
// component=Button
import figma from 'figma'
const instance = figma.selectedInstance
const label = instance.getString('Label')
const variant = instance.getEnum('Variant', {
'Primary': 'primary',
'Secondary': 'secondary',
})
const size = instance.getEnum('Size', {
'Small': 'sm',
'Medium': 'md',
'Large': 'lg',
})
const disabled = instance.getBoolean('Disabled')
const hasIcon = instance.getBoolean('Has Icon')
const icon = hasIcon ? instance.getInstanceSwap('Icon') : null
let iconCode
if (icon && icon.type === 'INSTANCE') {
iconCode = icon.executeTemplate().example
}
export default {
example: figma.code`
<Button
variant="${variant}"
size="${size}"
${disabled ? 'disabled' : ''}
${iconCode ? figma.code`icon={${iconCode}}` : ''}
>
${label}
</Button>
`,
imports: ['import { Button } from "primitives"'],
id: 'button',
metadata: { nestable: true }
}
ステップ 6: ファイルを読み返して、構文を確認します。
追加リファレンス
高度なパターン(複数レベルのネストされたコンポーネント、findConnectedInstances によるフィルタリング、親/子テンプレート間でのメタデータプロパティの受け渡し)については、次を参照してください:
- api.md — Code Connect API の完全なリファレンス
- advanced-patterns.md — 高度なネスト、メタデータプロパティ、子孫パターン