建立與維護將 Figma 元件對映至程式碼片段的 Figma Code Connect 範本檔案。當使用者提及 Code Connect、Figma 元件對映、設計轉程式碼(design-to-code),或要求建立/更新 .figma.ts 或 .figma.js 檔案時使用。
Code Connect
概述
建立將 Figma 元件對映至程式碼片段的 Code Connect 範本檔案 (.figma.ts)。給定 Figma URL 後,請依循以下步驟建立範本。
您「只能」撰寫
.figma.ts範本檔案 — 絕不要撰寫.figma.tsx。 此 Skill 所產出的為 Parserless 範本:一個預設匯出使用figma.code`...`標籤範本字串(tagged template)的.figma.ts檔案。切勿撰寫.figma.tsx檔案,也切勿使用figma.connect()— 那是另一種基於解析器(parser-based) 的 Code Connect 格式(發布方式不同),且對此 Skill 而言是錯誤的產物;若輸出撰寫為.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 團隊庫(team library)的元件。若元件尚未發布,請告知使用者並停止執行。
- 需要 Organization 或 Enterprise 方案 — 免費(Free)或專業版(Professional)方案不支援 Code Connect。
- URL 必須包含
node-id— Figma URL 必須包含node-id查詢參數。 - TypeScript 型別 — 為了在
.figma.ts檔案中提供編輯器自動完成與型別檢查,必須在tsconfig.json的types中新增@figma/code-connect/figma-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 可能指向 Frame、Instance 或 Variant,不一定是 Component Set 或獨立 Component。呼叫 MCP 工具 get_code_connect_suggestions 並帶入:
fileKey— 來自步驟 1nodeId— 來自步驟 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。後續所有步驟皆請使用這些解析後的節點 ID(而非 URL 中的原始 ID)。若傳回多個元件(例如使用者選取了包含數個不同元件實例的 Frame),請對每個元件重複步驟 3–6。
步驟 3:取得元件屬性
呼叫 MCP 工具 get_context_for_code_connect 並帶入:
fileKey— 來自步驟 1nodeId— 步驟 2 解析出的mainComponentNodeIdclientFrameworks— 從figma.config.json的parser欄位決定(例如"react"→["react"])clientLanguages— 從專案副檔名推斷(例如 TypeScript 專案 →["typescript"],JavaScript 專案 →["javascript"])
若有多個元件,每個節點 ID 呼叫一次該工具。
回應中會包含 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 屬性進行比較 — 尋找相符的 Variant 型別、尺寸選項、Boolean 旗標與 Slot Props
- 若有多個候選元件符合,選擇 Prop 介面最適配者,並向使用者說明理由
- 若未找到相符項,顯示最接近的 2 個候選元件,並請使用者確認或提供正確路徑
在進入步驟 5 之前,請與使用者確認。呈現比對結果:您找到了哪個程式碼元件、存放位置,以及相符的原因(Prop 對應關係、命名、用途)。
讀取 figma.config.json 以了解匯入路徑別名(import path aliases)— importPaths 區段將通配符模式對映至匯入指定符(import specifiers),而 paths 區段則將這些指定符對映至目錄。
讀取程式碼元件的原始碼以了解其 Props 介面 — 這將指引如何在步驟 5 中將 Figma 屬性對映至程式碼 Props。
步驟 5:建立範本檔案 (.figma.ts)
檔案位置
將檔案放置於現有 Code Connect 檔案旁。檢查 figma.config.json 的 include 模式以確認正確目錄。檔案命名為 ComponentName.figma.ts — 絕不要命名為 ComponentName.figma.tsx。 .figma.tsx 副檔名為基於解析器(parser-based)的格式;切勿建立該格式或修改現有的 .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: ... }) |
切換可見性、條件式 Props |
| VARIANT | instance.getEnum('Name', { 'FigmaVal': 'codeVal' }) |
尺寸、變體、狀態列舉 |
| INSTANCE_SWAP | instance.getInstanceSwap('Name') |
固定元件插槽的替換實例(接著使用 hasCodeConnect() / executeTemplate())- 切勿與下方的 SLOT 屬性混淆 |
| SLOT | instance.getSlot('Name') |
僅在 Figma 屬性型別為 SLOT 時用於自由內容插槽 |
| (child layer) | instance.findInstance('LayerName') |
無屬性的具名子實例 |
| (text layer) | 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 — 布林值或對映至特定數值:
// 純布林值
const disabled = instance.getBoolean('Disabled')
// 對映至程式碼數值(例如程式碼 Prop 為列舉型別而非布林值時)
const size = instance.getBoolean('Show Label', { true: 'large', false: 'small' })
當存在有效對應關係時,將 Figma 屬性對映至程式碼 Props。 Figma 屬性與程式碼 Props 不一定 1:1 完全對齊 — 部分 Figma 屬性可直接對映(透過名稱或上述 API 方法),其餘則無對應的程式碼屬性。有對映關係時請予以使用;若無合適項,請省略該 Figma 屬性,而非憑空製造程式碼 Prop。切勿輸出名稱未出現在程式碼元件 Props 介面中的屬性。
完整變體列舉處理
當 VARIANT 屬性具備多個可能數值時,getEnum 對映必須完整列出 get_context_for_code_connect 傳回的每一個數值。切勿遺漏數值 — 未對映的數值會靜默傳回 undefined,進而產生壞掉的輸出。
// 錯誤 — 遺漏了 'Warning',會渲染為 undefined
const status = instance.getEnum('Status', {
'Success': 'success',
'Error': 'error',
})
// 正確 — 每個數值皆已進行對映
const status = instance.getEnum('Status', {
'Success': 'success',
'Error': 'error',
'Warning': 'warning',
'Info': 'info',
})
當兩個或多個 VARIANT 屬性組合產生不同的程式碼輸出時,請產生完整的條件分支。例如:2 個 Variant × 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 不會改變程式碼片段的結構 — 僅作為 Prop 傳入),則每個 Variant 使用單一 getEnum 對映即足夠,無須建立交叉乘積分支。
INSTANCE_SWAP — 存取可替換的元件實例:
const icon = instance.getInstanceSwap('Icon')
let iconCode
if (icon && icon.type === 'INSTANCE') {
iconCode = icon.executeTemplate().example
}
SLOT — 只有當步驟 3 取得的 Figma 元件屬性型別為 SLOT 時,getSlot(propName) 才為有效用法。請勿將 getSlot() 用於 INSTANCE_SWAP 屬性(後者應使用 getInstanceSwap())。Slot 是元件定義中明確劃分的「內容區域」,而非泛指的巢狀實例。
- 簽章(Signature):
getSlot(propName: string): ResultSection[] | undefined
// Figma property "Content" must be type SLOT in component
<!-- truncated for translation batch; full body continues in source -->






