figma-code-connect

figma-code-connect

热门

创建并维护 Figma Code Connect 模板文件,用于将 Figma 组件映射到代码片段。当用户提及 Code Connect、Figma 组件映射、设计稿转代码(design-to-code),或要求创建/更新 .figma.ts、.figma.js 文件时使用此 Skill。

1838Star
171Fork
更新于 2026/7/30
SKILL.md
只读
名称
figma-code-connect
描述

创建并维护 Figma Code Connect 模板文件,用于将 Figma 组件映射到代码片段。当用户提及 Code Connect、Figma 组件映射、设计稿转代码(design-to-code),或要求创建/更新 .figma.ts、.figma.js 文件时使用此 Skill。

Code Connect

概述

创建将 Figma 组件映射到代码片段的 Code Connect 模板文件 (.figma.ts)。获取 Figma URL 后,按照以下步骤创建模板。

注意:你只能编写 .figma.ts 模板文件,绝不能编写 .figma.tsx 本 Skill 生成的是无解析器模板(parserless templates):即默认导出中使用 figma.code`...` 标签模板的 .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)的组件。如果组件未发布,请告知用户并停止操作。
  • 需要 Enterprise 或 Organization 团队计划 —— Code Connect 在免费版(Free)或专业版(Professional)计划中不可用。
  • URL 必须包含 node-id —— Figma URL 中必须包含 node-id 查询参数。
  • TypeScript 类型定义 —— 为了在 .figma.ts 文件中获得编辑器自动补全和类型检查,必须在 tsconfig.jsontypes 中添加 @figma/code-connect/figma-types
    {
      "compilerOptions": {
        "types": ["@figma/code-connect/figma-types"]
      }
    }
    

步骤 1:解析 Figma URL

从 URL 中提取 fileKeynodeId

URL 格式 fileKey nodeId
figma.com/design/:fileKey/:name?node-id=X-Y :fileKey X-YX:Y
figma.com/file/:fileKey/:name?node-id=X-Y :fileKey X-YX:Y
figma.com/design/:fileKey/branch/:branchKey/:name 使用 :branchKey 提取自 node-id 参数

务必将 nodeId 中的连字符转换为冒号:1234-56781234:5678

完整示例:

给定 URL:https://www.figma.com/design/QiEF6w564ggoW8ftcLvdcu/MyDesignSystem?node-id=4185-3778

  • fileKey = QiEF6w564ggoW8ftcLvdcu
  • nodeId = 4185-37784185:3778

步骤 2:发现未映射的组件

用户提供的 URL 可能指向画板(frame)、实例(instance)或变体(variant),而不一定是组件集(component set)或独立组件。使用以下参数调用 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"(在此选择中的所有组件实例均已通过 Code Connect 连接到代码) —— 所有内容已完成映射。告知用户并停止操作。
  • 包含组件列表的正常响应 —— 提取每个返回组件的 mainComponentNodeId。在后续所有步骤中,请使用这些解析后的节点 ID(而非 URL 中的原始 ID)。如果返回了多个组件(例如用户选择了一个包含多个不同组件实例的画板),请对每个组件重复步骤 3–6。

步骤 3:获取组件属性

使用以下参数调用 MCP 工具 get_context_for_code_connect

  • fileKey —— 提取自步骤 1
  • nodeId —— 步骤 2 中解析出的 mainComponentNodeId
  • clientFrameworks —— 根据 figma.config.jsonparser 字段确定(例如 "react"["react"]
  • clientLanguages —— 根据项目文件扩展名推断(例如 TypeScript 项目 → ["typescript"],JavaScript 项目 → ["javascript"]

若存在多个组件,请为每个节点 ID 分别调用一次该工具。

响应结果中包含 Figma 组件的属性定义 —— 请注意每个属性的名称与类型:

  • TEXT —— 文本内容(标签、标题、占位符)
  • BOOLEAN —— 开关控制(显示/隐藏图标、禁用状态)
  • VARIANT —— 枚举选项(尺寸、变体、状态)
  • INSTANCE_SWAP —— 绑定到特定组件的可替换嵌套实例(图标、头像)
  • SLOT —— 灵活的内容区域(自由布局、混合子节点);在模板中使用 getSlot()(与 INSTANCE_SWAP 不同)

保存此属性列表 —— 你将在步骤 5 编写模板时用到它。

步骤 4:识别代码组件

如果用户未明确说明要连接哪个代码组件:

  1. 检查 figma.config.json 中的 pathsimportPaths,查找组件所在的位置
  2. 在代码库中搜索与 Figma 组件名称匹配的代码组件。若 figma.config.json 未指定路径,请检查常见目录(src/components/components/lib/ui/app/components/
  3. 读取候选文件,对比其 Props 接口与步骤 3 获取的 Figma 属性 —— 查找匹配的变体类型、尺寸选项、布尔标记和插槽 Props
  4. 如果存在多个匹配的候选组件,挑选 Props 接口契合度最高的那个,并向用户说明你的判断理由
  5. 如果未找到匹配组件,展示契合度最高的 2 个候选组件,并请用户确认或提供正确的路径

在继续执行步骤 5 前与用户进行确认。展示匹配结果:找到了哪个代码组件、位于何处,以及匹配原因(Props 对应关系、命名、用途)。

读取 figma.config.json 以获取导入路径别名 —— importPaths 部分将 glob 模式映射到导入标识符,paths 部分将这些标识符映射到实际目录。

读取代码组件的源码以了解其 Props 接口 —— 这将为步骤 5 中如何将 Figma 属性映射到代码 Props 提供依据。

步骤 5:创建模板文件 (.figma.ts)

文件位置

将文件放置在现有 Code Connect 文件同级目录下。检查 figma.config.jsoninclude 模式以确定正确的目录。将其命名为 ComponentName.figma.ts —— 切勿命名为 ComponentName.figma.tsx .figma.tsx 扩展名属于基于解析器的格式;不要创建此类文件,也不要修改已有的此类文件。

模板结构

每个模板文件均遵循以下结构:

// url=https://www.figma.com/file/{fileKey}/{fileName}?node-id={nodeId}
// source={步骤 4 中代码组件的路径}
// component={步骤 4 中代码组件的名称}
import figma from 'figma'
const instance = figma.selectedInstance

// 从 Figma 组件中提取属性(参见下方的属性映射)
// ...

export default {
  example: figma.code`<Component ... />`,       // 必需:代码片段
  imports: ['import { Component } from "..."'], // 可选:导入语句
  id: 'component-name',                         // 必需:唯一标识符
  metadata: {                                    // 可选
    nestable: true,                              // true = 在父级中内联,false = 显示为胶囊块(pill)
    props: {}                                    // 可供父级模板访问的数据
  }
}

属性映射

使用步骤 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 个变体 × 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 透传),则每个变体使用单个 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) 才有效。切勿对 INSTANCE_SWAP 属性使用 getSlot()(该属性应使用 getInstanceSwap())。Slot 是组件定义中明确划定的“内容区域”,而非通用的嵌套实例。

  • 方法签名: getSlot(propName: string): ResultSection[] | undefined
// Figma 组件中的 "Content" 属性类型必须为 SLOT

<!-- truncated for translation batch; full body continues in source -->