关于 figma-generate-design
figma-generate-design 是用于在 Figma 中创建或更新组合式界面的技能,借助已发布设计系统中的组件、变量和样式。它为设计与编码 Agent 提供组件发现步骤和有序工作流。
主要功能
- 01创建组合式 Figma 界面
- 02复用设计系统组件与令牌
- 03查找组件键、变量和样式
- 04遵循分阶段工作流
- 05将网页布局捕获为视觉参考
适用场景
- 01根据现有 UI 代码创建多区块页面
- 02使用库组件更新模态框或侧边栏
- 03将网页界面与浏览器捕获结果对齐
MCP 相关
需要连接 Figma MCP 服务,并通过 `use_figma` 检查和修改 Figma 文件。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ thedesignproject/ agent-skills --skill figma-generate-design安装后在 Claude Code 中输入/figma-generate-design确认已加载。
详细介绍
使用设计系统构建 / 更新屏幕和视图
使用此技能在 Figma 中创建或更新屏幕、视图和多分区 UI 容器,方法是复用已发布的设计系统——组件、变量和样式,而不是使用硬编码值绘制基本图形。这包括完整页面、模态框、对话框、抽屉、侧边栏、面板,以及任何包含多个分区的组合视图。关键在于:Figma 文件可能已发布设计系统,其中包含组件、颜色 / 间距变量以及文本 / 效果样式,它们与代码库中的 UI 组件和设计令牌相对应。请找到并使用这些资源,而不是用十六进制颜色绘制方框。
强制要求:在调用任何 use_figma 之前,还必须加载 figma-use。该技能包含关键规则(颜色范围、字体加载等),适用于你编写的每个脚本。
在此技能中调用 use_figma 时,始终传入 skillNames: "figma-generate-design"。 这是一个日志记录参数,不会影响执行。
技能适用范围
- 如果交付内容是由设计系统组件实例构建的组合 Figma 视图(新建或更新),例如完整页面屏幕、模态框、对话框、抽屉、侧边栏、面板或任何多分区容器,请使用此技能。
- 如果用户想创建新的可复用组件或变体,请直接使用 figma-use。
- 如果用户想编写 Code Connect 映射,请切换到 figma-code-connect。
前置条件
- 必须连接 Figma MCP 服务
- 目标 Figma 文件必须包含已发布的设计系统及其组件(或可访问团队库)
- 用户应提供以下任一信息:
- 要编辑的 Figma 文件 URL / 文件 key
- 或目标文件的相关背景(Agent 可以查找页面)
- 要构建 / 更新的屏幕 / 视图的源代码或描述
使用 generate_figma_design 的并行工作流(仅适用于 Web 应用)
从可在浏览器中渲染的 Web 应用构建屏幕时,并行运行两种方法可以获得最佳效果:
- 并行执行:
- 使用此技能的工作流(use_figma + 设计系统组件)开始构建屏幕
- 运行
generate_figma_design,捕获正在运行的 Web 应用的像素级精确截图
- 两者都完成后: 更新 use_figma 的输出,使其匹配
generate_figma_design截图中的像素级精确布局。截图提供了准确的间距、尺寸和视觉效果目标,而 use_figma 的输出则包含与设计系统关联的正确组件实例。如果截图中包含图片,请将截图中图片填充的imageHash值复制到 use_figma 的输出中(详见步骤 5)。 - 确认效果良好后: 删除
generate_figma_design的输出——它仅用于视觉参考。
这样可以兼得两者的优势:generate_figma_design 能准确还原像素级布局,而 use_figma 能生成与设计系统关联且可更新的正确组件实例。
源内容包含图片时,必须使用此并行工作流。 use_figma Plugin API 无法获取外部图片 URL——它只能通过复制文件中现有节点的 imageHash 值来设置图片填充。generate_figma_design 会将所有可见图片栅格化并导入 Figma,从而提供所需的哈希值。如果图片存在但跳过截图步骤,图片框将会留空。
对于非 Web 应用(iOS、Android 等)或更新现有屏幕,请使用下方的标准工作流。
必需工作流
按顺序执行以下步骤。不要跳过任何步骤。
硬性门槛 — 禁止走捷径:
- 禁止: 在完成 2a-i 且尝试了 2a-ii 或记录为 N/A(例如“文件为空,没有现有界面”)之前,使用
search_design_system搜索组件键。- 禁止: 在下方清单中的第 2 步所有行都填写完成之前,进行任何会修改画布的
use_figma调用(第 3 步及之后)。
第 1 步:了解交付内容
开始操作 Figma 之前,先了解你要构建的内容:
- 如果根据代码构建,请阅读相关源文件,了解结构、各个部分以及使用的组件。
- 确定视图中的主要部分(例如,页面:页眉、主视觉区、内容面板、页脚;模态框:标题栏、表单区块、操作栏;侧边栏:导航、内容区、页脚操作)。
- 列出每个部分涉及的 UI 组件(按钮、输入框、卡片、导航选项卡、手风琴组件等)。
- 检查视图是否包含任何图像(例如,
<img>、<Image>、背景图、产品照片、头像、从 URL 加载的图标)。如果包含图像且这是一个 Web 应用,你必须运行并行的generate_figma_design捕获工作流——立即与第 2 步同时启动,以便在发现组件期间进行捕获。请参阅上方的“与 generate_figma_design 并行的工作流”。
第 2 步:收集组件键、变量和样式
你需要从设计系统中获取三项内容:组件(按钮、卡片等)、变量(颜色、间距、圆角半径)和样式(文本样式、阴影等效果样式)。设计系统中存在令牌时,不要对十六进制颜色或像素值进行硬编码。
2a:发现组件
2a-i — 必须:检查所需组件是否存在 Code Connect。 从你在步骤 1 中整理的组件列表开始,检查代码库中的每个组件是否都有 Code Connect 文件。Code Connect 文件位于组件源文件旁边,并按平台命名:
- TypeScript/JS:
*.figma.ts、*.figma.js - React(基于解析器):
*.figma.tsx - Kotlin/Compose:包含
@FigmaConnect的.kt文件 - Swift:包含
FigmaConnect的.swift文件
对于所需的每个组件(例如 Button、Card、Input),搜索其 Code Connect 文件——按组件名称使用 glob 或 grep 搜索(例如 **/Button.figma.tsx、**/Card.figma.ts)。只读取与实际所需组件匹配的文件。
从每个匹配的 Code Connect 文件中提取 Figma 组件 URL。从 URL 中解析 fileKey 和 nodeId(将连字符转换为冒号:123-456 → 123:456)。然后通过 use_figma 解析组件键:
示例: Code Connect 文件包含 // url=https://figma.com/design/ABC123/File?node-id=609-35535。解析得出 fileKey = ABC123,nodeId = 609:35535。针对库文件(fileKey 为 ABC123,而非目标文件)运行 use_figma,以解析组件键:
const node = await figma.getNodeByIdAsync("609:35535");
const set = node?.parent?.type === "COMPONENT_SET" ? node.parent : node;
return { componentKey: set.key };
在一次调用中批量执行多次查询。在步骤 4 中使用返回的键调用 importComponentSetByKeyAsync()。
标记已解析的组件。如果所有组件都已解析,则跳过 2a-ii 和 2a-iii。如果所需组件均没有 Code Connect 文件,则继续执行 2a-ii。
2a-ii — 仍有未解析组件时必须执行:检查现有界面。 检查目标文件是否已包含使用相同设计系统的界面。一次 use_figma 调用遍历现有画框的实例,即可提供精确且权威的组件映射:
// Read-only discovery — skip invisible content inside instances (hidden
// variants etc.) for the hundreds-of-times-faster findAllWithCriteria.
figma.skipInvisibleInstanceChildren = true;
const frame = figma.currentPage.findOne(n => n.name === "Existing Screen");
const uniqueSets = new Map();
frame.findAllWithCriteria({ types: ["INSTANCE"] }).forEach(inst => {
const mc = inst.mainComponent;
const cs = mc?.parent?.type === "COMPONENT_SET" ? mc.parent : null;
const key = cs ? cs.key : mc?.key;
const name = cs ? cs.name : mc?.name;
if (key && !uniqueSets.has(key)) {
uniqueSets.set(key, { name, key, isSet: !!cs, sampleVariant: mc.name });
}
});
return [...uniqueSets.values()];
将结果与尚未解析的组件进行匹配。标记新解析的组件。如果所有组件都已解析,则跳过 2a-iii。
2a-iii — 最后的手段:search_design_system。 仅当完成 2a-i 和 2a-ii 后仍有组件未解析时才执行。
搜索前,调用 get_libraries,查看文件可用的库。此调用会返回两个列表:已添加到文件的库,以及可添加的库(社区 UI 套件和组织库)。每个条目都包含一个 libraryKey,你可以通过 includeLibraryKeys 参数将其传给 search_design_system,把搜索范围限定在特定库,而不是搜索所有内容。
// Step 1: Discover available libraries
get_libraries({ fileKey })
// Returns: {
// libraries_added_to_file: [...],
// libraries_available_to_add: [...],
// libraries_available_to_add_next_offset: number | null
// }
// Step 2: Search within a specific library using its libraryKey
search_design_system({ query: "button", fileKey, includeLibraryKeys: ["lk-abc123..."] })
libraries_available_to_add 中的组织库采用分页方式(每页 20 个)。当 libraries_available_to_add_next_offset 不为 null 时,表示还有更多组织库可用——使用该值作为 offset 再次调用 get_libraries,以获取下一页。社区 UI 套件仅出现在第一页。如果用户指定的库在当前页中未显示,请继续翻页查找,不要轻易放弃。
当文件包含许多库,而你希望获得针对性结果时,这尤其有用(例如,仅搜索“iOS 26”或“Material 3”,而不是从所有库中获取匹配结果)。
广泛搜索——尝试多个词语及其同义词(例如“button”“input”“nav”“card”“accordion”“header”“footer”“tag”“avatar”“toggle”“icon”等)。使用 includeComponents: true,将搜索重点放在组件上。
将组件属性纳入映射——你需要了解每个组件公开了哪些 TEXT 属性,以便覆盖文本。创建一个临时实例,读取其 componentProperties(以及嵌套实例的 componentProperties),然后移除临时实例。
包含属性信息的组件映射示例:
Component Map:
- Button → key: "abc123", type: COMPONENT_SET
Properties: { "Label#2:0": TEXT, "Has Icon#4:64": BOOLEAN }
- PricingCard → key: "ghi789", type: COMPONENT_SET
Properties: { "Device": VARIANT, "Variant": VARIANT }
Nested "Text Heading" has: { "Text#2104:5": TEXT }
Nested "Button" has: { "Label#2:0": TEXT }
2b:发现变量(颜色、间距、圆角)
先检查现有屏幕(与组件相同)。也可以使用 search_design_system,并设置 includeVariables: true。
警告:变量发现有两种不同的方法,请勿混淆。
use_figma配合figma.variables.getLocalVariableCollectionsAsync()— 只返回当前文件中定义的本地变量。如果返回空结果,并不意味着不存在变量。此 API 无法访问远程或已发布的库变量。search_design_system配合includeVariables: true— 搜索所有已链接的库,包括远程和已发布的库。这才是发现设计系统变量的正确工具。切勿仅因
getLocalVariableCollectionsAsync()返回空结果,就得出“没有变量”的结论。 在决定自行创建变量之前,务必同时运行search_design_system并设置includeVariables: true,以检查库变量。
查询策略: search_design_system 会根据变量名称(例如 “Gray/gray-9”、“core/gray/100”、“space/400”)进行匹配,而不是根据类别。请并行运行多个简短、简单的查询,而不要使用一个复合查询:
- 基元颜色: “gray”、“red”、“blue”、“green”、“white”、“brand”
- 语义颜色: “background”、“foreground”、“border”、“surface”、“text”
- 间距/尺寸: “space”、“radius”、“gap”、“padding”
如果初次搜索没有结果,请尝试更短的片段或不同的命名约定——各个库的命名方式差异很大(例如 “grey” 与 “gray”、“spacing” 与 “space”、“color/bg” 与 “background”)。
检查现有屏幕绑定的变量,以获得最权威的结果:
// Read-only discovery — skip invisible instance interiors for speed.
figma.skipInvisibleInstanceChildren = true;
const frame = figma.currentPage.findOne(n => n.name === "Existing Screen");
// boundVariables can live on any scene node — enumerating every scene type
// just to feed findAllWithCriteria is roughly the same as findAll(() => true)
// and is much noisier in script output.
const uniqueIds = new Set(
frame.findAll(() => true).flatMap(n =>
Object.values(n.boundVariables ?? {})
.flatMap(b => Array.isArray(b) ? b : [b])
.map(b => b?.id)
.filter(Boolean)
)
);
const variables = await Promise.all(
[...uniqueIds].map(id => figma.variables.getVariableByIdAsync(id))
);
return variables
.filter(Boolean)
.map(v => ({ name: v.name, id: v.id, key: v.key, type: v.resolvedType, remote: v.remote }));
对于库变量(remote = true),使用 figma.variables.importVariableByKeyAsync(key) 按键导入。对于本地变量,直接使用 figma.variables.getVariableByIdAsync(id)。
有关绑定模式,请参阅 variable-patterns.md。
2c:发现样式(文本样式、效果样式)
使用 search_design_system 并设置 includeStyles: true,搜索 “heading”、“body”、“shadow”、“elevation” 等词,以查找样式。也可以检查现有屏幕使用的样式:
// Read-only discovery — skip invisible instance interiors for speed.
figma.skipInvisibleInstanceChildren = true;
const frame = figma.currentPage.findOne(n => n.name === "Existing Screen");
const styles = { text: new Map(), effect: new Map() };
for (const node of frame.findAll(() => true)) {
// textStyleId is on TEXT and TEXT_PATH; effectStyleId is on most scene
// shape/container types. Use `in` guards to handle both without an
// exhaustive type list.
if ('textStyleId' in node && node.textStyleId) {
const s = figma.getStyleById(node.textStyleId);
if (s) styles.text.set(s.id, { name: s.name, id: s.id, key: s.key });
}
if ('effectStyleId' in node && node.effectStyleId) {
const s = figma.getStyleById(node.effectStyleId);
if (s) styles.effect.set(s.id, { name: s.name, id: s.id, key: s.key });
}
}
return {
textStyles: [...styles.text.values()],
effectStyles: [...styles.effect.values()]
};
使用 figma.importStyleByKeyAsync(key) 导入库样式,然后通过 node.textStyleId = style.id 或 node.effectStyleId = style.id 应用。
详情请参阅 text-style-patterns.md 和 effect-style-patterns.md。
步骤 3:先创建包装框架
不要将各个区块创建为页面顶层子节点,之后再重新设置父级——在不同的 use_figma 调用之间移动节点时,appendChild() 会静默失败,导致框架成为孤立节点。应先创建包装框架,然后直接在其中构建各个区块。
在单独的 use_figma 调用中创建包装框架。将其放置在远离现有内容的位置,并返回其 ID:
// Find clear space
let maxX = 0;
for (const child of figma.currentPage.children) {
maxX = Math.max(maxX, child.x + child.width);
}
const wrapper = figma.createAutoLayout("VERTICAL");
// --- Size the wrapper based on container type ---
// Full page: wrapper.resize(1440, 100); wrapper.name = "Homepage";
// Modal/dialog: wrapper.resize(640, 100); wrapper.name = "Settings Modal";
// Drawer/sidebar: wrapper.resize(360, 100); wrapper.name = "Navigation Drawer";
// Panel: wrapper.resize(400, 100); wrapper.name = "Details Panel";
// Adapt width to match the source code's actual dimensions.
wrapper.name = "VIEW_NAME";
wrapper.primaryAxisAlignItems = "CENTER";
wrapper.counterAxisAlignItems = "CENTER";
wrapper.resize(WIDTH, 100);
wrapper.layoutSizingHorizontal = "FIXED";
wrapper.x = maxX + 200;
wrapper.y = 0;
return { success: true, wrapperId: wrapper.id };
步骤 4:在包装框架内构建各个区块
这是最重要的一步。 一次构建一个区块,每个区块都使用单独的 use_figma 调用。在每个脚本开头,按 ID 获取包装框架,并将新内容直接添加到其中。
const createdNodeIds = [];
// Resolve the wrapper and import every design system dependency in parallel.
// Sequential awaits here serialize N independent IPC round-trips at the top
// of every section build; one Promise.all is dramatically faster.
const [wrapper, buttonSet, bgColorVar, spacingVar, shadowStyle] = await Promise.all([
figma.getNodeByIdAsync("WRAPPER_ID_FROM_STEP_3"),
figma.importComponentSetByKeyAsync("BUTTON_SET_KEY"),
figma.variables.importVariableByKeyAsync("BG_COLOR_VAR_KEY"),
figma.variables.importVariableByKeyAsync("SPACING_VAR_KEY"),
figma.importStyleByKeyAsync("SHADOW_STYLE_KEY"),
]);
const primaryButton = buttonSet.children.find(c =>
c.type === "COMPONENT" && c.name.includes("variant=primary")
) || buttonSet.defaultVariant;
// Build section frame with variable bindings (not hardcoded values)
const section = figma.createAutoLayout();
section.name = "Header";
section.setBoundVariable("paddingLeft", spacingVar);
section.setBoundVariable("paddingRight", spacingVar);
const bgPaint = figma.variables.setBoundVariableForPaint(
{ type: 'SOLID', color: { r: 0, g: 0, b: 0 } }, 'color', bgColorVar
);
section.fills = [bgPaint];
// Apply the effect style imported above
section.effectStyleId = shadowStyle.id;
// Create component instances inside the section
const btnInstance = primaryButton.createInstance();
section.appendChild(btnInstance);
createdNodeIds.push(btnInstance.id);
// Append section to wrapper
wrapper.appendChild(section);
section.layoutSizingHorizontal = "FILL"; // AFTER appending
createdNodeIds.push(section.id);
return { success: true, createdNodeIds };
每完成一个区块后,都使用 get_screenshot 验证,再继续下一步。仔细检查文本是否被裁切/截断(行高导致内容被切掉)以及元素是否重叠——这些是最常见的问题,而且很容易被忽略。
使用 setProperties() 覆盖实例文本
组件实例自带占位文本(“Title”“Heading”“Button”)。使用你在步骤 2 中找到的组件属性键,通过 setProperties() 覆盖这些文本——这种方式比直接操作 node.characters 更可靠。完整模式请参阅 component-patterns.md。
对于暴露了自身 TEXT 属性的嵌套实例,请在嵌套实例上调用 setProperties():
// Use the type-indexed criteria for the type filter, then narrow by name.
const nestedHeading = cardInstance
.findAllWithCriteria({ types: ["INSTANCE"] })
.find(n => n.name === "Text Heading");
if (nestedHeading) {
nestedHeading.setProperties({ "Text#2104:5": "Actual heading from source code" });
}
只有当文本不受任何组件属性管理时,才退而使用直接操作 node.characters 的方式。
仔细检查源代码中的默认值
将代码组件转换为 Figma 实例时,请检查源代码中组件的默认属性值,而不只是检查显式传入的值。例如,对于 <Button size="small">Register</Button>,如果没有指定 variant 属性,请检查组件定义,确认默认值是否为 variant = "primary"。选择错误的变体(例如 Neutral 而不是 Primary)会导致视觉效果不正确,而且很容易被忽略。
哪些内容应手动构建,哪些应从设计系统导入
| 手动构建 | 从设计系统导入 |
|---|---|
| 外层框架 | 组件:按钮、卡片、输入框、导航等 |
| 区块容器框架 | 变量:颜色(填充、描边)、间距(内边距、间隙)、圆角 |
| 布局网格(行、列) | 文本样式:标题、正文、说明文字等 |
| 效果样式:阴影、模糊等 |
如果设计系统中存在变量,绝不要硬编码十六进制颜色或像素间距。 使用 setBoundVariable 设置间距和圆角,使用 setBoundVariableForPaint 设置颜色。通过 node.textStyleId 应用文本样式,通过 node.effectStyleId 应用效果样式。
步骤 5:验证完整视图并传输图像
组合好所有区块后,对外层框架调用 get_screenshot,并与源内容进行比较。使用有针对性的 use_figma 调用修复问题——不要重建整个视图。
截取各个区块的截图,而不只是完整视图。 降低分辨率后的完整视图截图会掩盖文本截断、颜色错误以及尚未覆盖的占位文本。按节点 ID 截取每个区块的截图,以发现以下问题:
- 文本被裁剪或截断——行高或框架尺寸导致下伸部、上伸部或整行文字被切掉
- 内容重叠——因尺寸错误或缺少自动布局,元素互相叠放
- 仍显示占位文本(“Title”“Heading”“Button”)
- 因布局尺寸错误而导致内容截断
- 组件变体错误(例如 Neutral 按钮而不是 Primary 按钮)
- 图像占位区域为空白——如果缺少图像,需要从
generate_figma_design捕获结果中传输图像(见下文)
从 generate_figma_design 捕获结果中传输图像
如果你并行运行了 generate_figma_design(源内容包含图像时必须运行),请将捕获的图像传输到设计系统输出中:
- 搜索
type === "IMAGE"的填充,在捕获结果中找到所有图像节点:// Read-only image inventory — skip invisible instance interiors for speed. figma.skipInvisibleInstanceChildren = true; const capture = await figma.getNodeByIdAsync("CAPTURE_NODE_ID"); const imageNodes = capture.findAll(() => true).flatMap(n => { if (!Array.isArray(n.fills)) return []; const imageFill = n.fills.find(f => f.type === "IMAGE"); return imageFill ? [{ name: n.name, id: n.id, imageHash: imageFill.imageHash }] : []; }); return imageNodes; - 将每个捕获的图像与
use_figma输出中对应的框架匹配(按位置、名称或顺序)。 - 将图像哈希应用到目标框架:
targetFrame.fills = [{ type: "IMAGE", imageHash: "hash_from_capture", scaleMode: "FILL" }]; - 传输完所有图像后,删除
generate_figma_design捕获结果。
步骤 6:更新现有视图
如果是更新而非从头创建:
- 使用
get_metadata检查现有屏幕结构。 - 确定哪些区块需要更新,哪些可以保留。
- 对于每个需要更改的区块:
- 按 ID 或名称定位现有节点
- 如果设计系统组件发生变化,则替换组件实例
- 根据需要更新文本内容、变体属性或布局
- 移除已弃用的区块
- 添加新区块
- 每次修改后使用
get_screenshot进行验证。
// Example: Swap a button variant in an existing screen.
// Batch the node lookup and component-set import in parallel — they are
// independent and awaiting them sequentially serializes two IPC round-trips.
const [existingButton, buttonSet] = await Promise.all([
figma.getNodeByIdAsync("EXISTING_BUTTON_INSTANCE_ID"),
figma.importComponentSetByKeyAsync("BUTTON_SET_KEY"),
]);
if (existingButton && existingButton.type === "INSTANCE") {
const newVariant = buttonSet.children.find(c =>
c.name.includes("variant=primary") && c.name.includes("size=lg")
) || buttonSet.defaultVariant;
existingButton.swapComponent(newVariant);
}
return { success: true, mutatedNodeIds: [existingButton.id] };
参考文档
如需了解详细的 API 模式和注意事项,请按需查阅 figma-use 中的参考文档:
- component-patterns.md — 按键导入、查找变体、setProperties、文本覆盖、使用实例
- variable-patterns.md — 创建/绑定变量、导入库变量、作用域、别名、发现现有变量
- text-style-patterns.md — 创建/应用文本样式、导入库文本样式、字号阶梯
- effect-style-patterns.md — 创建/应用效果样式(阴影)、导入库效果样式
- gotchas.md — 布局陷阱(HUG/FILL 交互、counterAxisAlignItems、尺寸设置顺序)、填充/颜色问题、页面上下文重置
错误恢复
遵循 figma-use 中的错误恢复流程:
- 遇到错误时停止 — 不要立即重试。
- 仔细阅读错误消息,了解出了什么问题。
- 如果错误不明确,请调用
get_metadata或get_screenshot检查当前文件状态。 - 根据错误消息修复脚本。
- 重试修正后的脚本 — 这是安全的,因为失败的脚本具有原子性(脚本报错时不会创建任何内容)。
由于此技能采用增量方式(每次调用处理一个分区),错误自然会限定在单个分区内。之前成功调用所创建的分区会保持不变。
最佳实践
- 构建前始终先搜索。 设计系统中很可能已有你需要的组件、变量或样式。手动构建和硬编码值应是例外,而非常规做法。
- 广泛搜索。 尝试同义词和部分词语。例如,“NavigationPill”可能可以通过“pill”、“nav”、“tab”或“chip”找到。对于变量,可搜索“color”、“spacing”、“radius”等。
- 优先使用设计系统令牌,而非硬编码值。 使用变量绑定设置颜色、间距和圆角;使用文本样式设置排版;使用效果样式设置阴影。这样屏幕就会与设计系统保持关联。
- 优先使用组件实例,而非手动构建。 实例会保持与源组件的关联,并在设计系统更新时自动更新。
- 逐个分区进行操作。 每次
use_figma调用最多构建一个主要分区。 - 每次调用都返回节点 ID。 后续组合分区和错误恢复时会用到它们。
- 每完成一个分区后都进行视觉验证。 使用
get_screenshot尽早发现问题。 - 遵循现有规范。 如果文件中已有屏幕,请沿用其命名、尺寸和布局模式。