mcpField
F
figma-code-connect

figma-code-connect

github.com/figma设计与 UI2.1k3.5k 次安装今天更新
代码仓库

关于 figma-code-connect

figma-code-connect 是用于创建 parserless Figma Code Connect 模板的技能,可将已发布的 Figma 组件关联到代码片段,并指导组件发现、属性映射及 `.figma.ts` 文件创建。

主要功能

  1. 01使用 `figma.code` 创建 `.figma.ts` 模板
  2. 02查找尚未映射的已发布组件
  3. 03将 Figma 属性映射到代码属性
  4. 04处理变体、插槽和实例替换

适用场景

  1. 01将已发布的 Figma 组件关联到代码组件
  2. 02根据 Figma 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

概述

创建 Code Connect 模板文件(.figma.ts),将 Figma 组件映射到代码片段。给定 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 方案 —— Free 或 Professional 方案不提供 Code Connect。
  • 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 格式fileKeynodeId
figma.com/design/:fileKey/:name?node-id=X-Y:fileKeyX-Y → X:Y
figma.com/file/:fileKey/:name?node-id=X-Y:fileKeyX-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 = QiEF6w564ggoW8ftcLvdcu
  • nodeId = 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。后续所有步骤都使用这些解析后的节点 ID,而不是 URL 中的原始 ID。如果返回多个组件(例如,用户选择的画框中包含多个不同的组件实例),请对每个组件重复第 3 至第 6 步。

步骤 3:获取组件属性

调用 MCP 工具 get_context_for_code_connect,并提供:

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

对于多个组件,每个节点 ID 调用一次工具。

响应包含 Figma 组件的属性定义——记录每个属性的名称和类型:

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

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

步骤 4:识别代码组件

如果用户未指定要连接哪个代码组件:

  1. 检查 figma.config.json 中的 paths 和 importPaths,查找组件所在位置
  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.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 属性类型模板方法使用场景
TEXTinstance.getString('Name')标签、标题、占位文本
BOOLEANinstance.getBoolean('Name', { true: ..., false: ... })切换可见性、条件属性
VARIANTinstance.getEnum('Name', { 'FigmaVal': 'codeVal' })尺寸、变体、状态枚举
INSTANCE_SWAPinstance.getInstanceSwap('Name')固定组件插槽中交换的实例(之后使用 hasCodeConnect() / executeTemplate())——不要与下方的 SLOT 属性混淆
SLOTinstance.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 属性与代码属性并不总是一一对应——有些 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',
})

当两个或更多 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 — 仅当第 3 步报告的 Figma 组件属性类型为 SLOT 时,getSlot(propName) 才有效。不要对 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>`——不要将其视为普通字符串
  • 裸布尔属性:使用条件表达式 → ${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)、但仍可独立配置的子实例——它们有自己的变体、属性或替换插槽。必须动态解析这些实例,不能将其硬编码。

  1. 检查子项是否已有 Code Connect 模板——使用 get_code_connect_suggestions,或检查项目中现有的 .figma.ts 文件。
  2. 如果没有模板,则为子项创建一个,确保它无论单独渲染还是嵌套渲染都能正常显示。
  3. 在父项中引用子项,使用 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 属性和子组件插槽都使用动态 API(getInstanceSwap()、findInstance()、findConnectedInstance() 等)和 executeTemplate()。插槽中不得包含硬编码的组件内容。
  • 规则与注意事项——检查下方列出的常见错误(模板结果的字符串拼接、不必要的 hasCodeConnect() 守卫、缺少 type === 'INSTANCE' 检查等)。
  • 插值包装——字符串(getString、getEnum、textContent)需用引号括起来,实例/区段值(executeTemplate().example)需用花括号括起来,插槽区段(getSlot)需作为代码片段区段插入 figma.code`...`,布尔值需使用条件表达式

如有任何不确定之处,请查阅 api.md 了解 API 详情,并查阅 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 属性
属性类型
.textContentstring
.namestring
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
}

规则和注意事项

  1. 绝不要拼接模板结果。 executeTemplate().example 是一个 ResultSection[] 对象,而不是字符串。使用 + 或 .join() 会生成 [object Object]。始终在带标签的模板中插值:figma.code`${snippet1}${snippet2}`

  2. 不要使用 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
    }
    
  3. 调用 executeTemplate() 前先检查 type === 'INSTANCE'。 findInstance()、findConnectedInstance() 和 findText() 在失败时会返回 ErrorHandle(真值,但不是实际节点),而不是 null。务必添加类型检查以避免崩溃:if (child && child.type === 'INSTANCE') { ... }

  4. 当插槽存在组件属性时,优先使用 getInstanceSwap(),而不是 findInstance()。 如果图标被替换为其他名称,findInstance('Star Icon') 就会失效;无论插槽中是哪种实例,getInstanceSwap('Icon') 都始终有效。

  5. 仅当 Figma 属性类型为 SLOT 时才使用 getSlot()。 对于 INSTANCE_SWAP 属性,请使用 getInstanceSwap()(返回一个 InstanceHandle)。getSlot() 返回结构化的插槽区段,而不是实例,绝不要对其返回值调用 executeTemplate()。

  6. 属性名称区分大小写,必须与 get_context_for_code_connect 返回的名称完全一致。

  7. 正确处理多个模板数组。 遍历子项时,将每个结果分别存入变量并逐一插值——不要使用 .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}` }
    
  8. 绝不要硬编码插槽或子项内容。 始终动态解析子实例——对 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>`
    
  9. 尝试通过代码属性表示每个 Figma 属性。 代码组件的 Props 接口(来自步骤 4)是属性名称的权威列表。对于每个 Figma 属性,使用步骤 5 中的 API 方法,确定合适的表示方式——名称直接匹配、转换值,或其他适用方式。如果没有任何代码属性适用,就省略它——不要编造属性名称。

完整示例

给定 URL:https://figma.com/design/abc123/MyFile?node-id=42-100

步骤 1: 解析 URL。

  • fileKey = abc123
  • nodeId = 42-100 → 42:100

步骤 2: 使用 fileKey: "abc123"、nodeId: "42:100"、excludeMappingPrompt: true 调用 get_code_connect_suggestions。 响应返回一个组件,其 mainComponentNodeId: "42:100"。如果响应为空,请停止并告知用户。如果返回了多个组件,请对每个组件重复步骤 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 组件。阅读其源代码以确认属性: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 过滤,以及父/子模板之间的元数据属性传递):

评论

支持 Markdown