figma-codegen
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesefigma-codegen
figma-codegen
Turn a Figma selection into code that looks like the rest of the project: reuse the components and
tokens that already exist, only build what's genuinely missing. The grounded tools do the heavy
lifting so you are not guessing from a screenshot. This file is the router; deep detail lives in
— load a reference when its step is in play.
references/将Figma选中内容转换为与项目其余部分风格一致的代码:重用已有的组件和令牌,仅构建真正缺失的部分。基于事实的工具会完成繁重的工作,让你无需从截图中猜测。本文件是路由;详细内容位于目录下——当执行到对应步骤时加载参考文档。
references/When to use
使用场景
- The user pastes a Figma URL/selection and asks for code ("code this", "build this component").
- The user wants to extend an existing component to match a Figma frame.
- 用户粘贴Figma URL/选中内容并要求生成代码(“把这个转为代码”、“构建这个组件”)。
- 用户希望扩展现有组件以匹配Figma框架。
Workflow
工作流程
Run the grounded tools against the selection, then generate — trust them over the rendered image.
-
(detail
get_design_context,full) → the structural tree with tokens resolved to names (dedupeComponents: true,Primary/500), styles deduped intospacing/4, and each instance'sglobalVars/mainComponent. This is the layout + binding source of truth. KeepcomponentPropertiesand don't depth-limit a subtree you'll build from. → How to read the tree, the per-node fidelity catalog (effects, per-side borders, stroke align, per-corner radius, blend, masks, gradients, image-fit, auto-layout/grid, aspect-ratio, scroll/sticky, stack & stroke-space), Dev Mode annotations as ground truth, and grounding a page too big for one call:dedupeComponents: true.references/grounding.md -
→ every Figma component grouped to a local code component with a
component_map(high / medium / low / unmapped),status, andcandidate.filePath.matchedProps- /
high: reuse that component (import frommedium), don't regenerate. Never invent a component namecandidate.filePathdidn't report.component_map - (a capped list of
candidate.ambiguousWith): the Figma name matched two or more code components nearly equally and the join couldn't confidently pick — a verify-me pick, not a confident reuse (the analogue of{ name, filePath }'stoken_map). Check which of the winningambiguousWith+ these runner-ups is the right component for this context before importing (a wrong reuse is a silent visual bug), then record the confirmed one in the map file so the next run is certain. Absent when the pick was unambiguous.candidate - Wire each entry's (resolved variant / boolean / text values) onto the reused component — one element per instance, with its own props.
instances[].props - : Figma axes the component has no prop for (a leading icon, a
candidate.unmatchedPropsflag, an active state) → surface as component-extension TODOs, never fake them with ad-hoc markup.required - : build it new in the project's style. For a repeated unmapped component (
unmapped), build from its first instance's subtree; if that came backinstanceCount > 1/deduped, drilltruncatedonget_design_contextonce — don't rebuild a repeated component by eye.instances[0].nodeId - When you're emitting a component's own definition (its prop types, not just rendering it),
on the component/instance returns the full property API — every VARIANT option and each BOOLEAN/TEXT/INSTANCE_SWAP prop with its default — so the prop space is grounded, not inferred from the instances you happened to see.
get_component_api
-
→ every Figma variable joined to a project token with
token_map+status+ref. A document's shared paint styles (single solid color styles — the token mechanism of pre-variables files) join the same way, markedmatchedBy.source: 'style'- mapped: reference (
candidate.ref,bg-primary-500) — never the raw hex/pxvar(--color-primary-500)resolved.get_design_contexton a colour (value drifted): use it but flag the mismatch.matchedBy: ['name'] - (several project tokens share that exact value and the name couldn't split them): a capped, verify-me pick — choose the semantically right sibling for the context (or keep the value and flag the gap), never treat it as a confirmed reuse.
candidate.ambiguousWith - On a document with few or no variables (most real-world files), 's own
get_design_contextmap is the fallback: any raw color in the payload that exactly equals a project token's value is annotated there (projectTokens). Before hardcoding a hex, look it up and emit the{ "#6266F0": { ref, name, matchedBy: ["value"] } }when it fits the context semantically.refmarks the entry as name-blind value-equality evidence — a hypothesis to verify, not a resolved binding: an entry withmatchedBy: ["value"]lists same-value tokens to choose between by meaning, a semantically wrong token is worse than the raw value (keep the raw value and note the gap instead), and a bound Figma variable always outranks a raw-value match.candidates - (Tailwind built-in scale step, e.g.
framework-builtin,spacing/4,line-height/7): carriesweight/Bold— compose the utility (builtin: { scale, step }/p-4,gap-4,leading-7), not an arbitraryfont-bold. This is not a gap.p-[16px] - : use the value but call out the gap (offer to add it to the token source); don't hardcode silently.
unmapped - (
figmaModes, with the file's theme axes on{ Light: …, Dark: … }): the token is theme-dependent —themedCollectionsis only the default mode, never the whole story. Mapped: emitfigmaValueand confirm the project token itself switches per theme (candidate.ref/.dark/[data-theme]/ aprefers-color-schemestory); if the project defines only one value, wire the other mode's value into that mechanism or surface a theme gap. Unmapped: the default mode is the base, other modes ride the project's dark-mode mechanism (dark:variants /dark:). Themes encoded without native modes — paired collections or name groups (prefers-color-scheme+Color/Light/*, a plan-limited workaround) — get the same treatment.Color/Dark/*
- mapped: reference
-
Export the assets grounding can't carry — logos, photos, icons have no pixels and otherwise render as grey blocks.for
save_image_fills-fill nodes (the original asset, not a clipped re-render),IMAGEfirst for icons (reuse curatedicon_maps),.svgonly for the composited look. → Full asset/icon/svg/colour-contract workflow:get_screenshot.references/assets-and-icons.md
Then emit code in the detected stack (the profile comes back on / ; you do
not call yourself): compose the reused components, wrap unmapped pieces, and apply
token references for colour/spacing/radius/typography.
component_maptoken_mapanalyze_project针对选中内容运行基于事实的工具,然后生成代码——优先信任工具结果而非渲染截图。
-
(详情级别
get_design_context,full)→ 已解析令牌名称(如dedupeComponents: true、Primary/500)的结构树,样式已去重为spacing/4,每个实例包含globalVars/mainComponent。这是布局与绑定的事实来源。保持componentProperties,不要限制你将构建的子树深度。 → 如何读取结构树、每个节点的保真度目录(效果、单边边框、描边对齐、圆角半径、混合模式、遮罩、渐变、图片适配、自动布局/网格、宽高比、滚动/粘性定位、堆叠与描边间距)、作为事实依据的Dev Mode注释,以及处理超出单次调用范围的大型页面:dedupeComponents: true。references/grounding.md -
→ 每个Figma组件与本地代码组件分组对应,包含
component_map(high / medium / low / unmapped)、status和candidate.filePath。matchedProps- /
high:重用该组件(从medium导入),不要重新生成。绝不要使用candidate.filePath未报告的组件名称。component_map - (一组有限的
candidate.ambiguousWith):Figma名称近乎匹配多个代码组件,无法确定最优选择——这是一个需要验证的选项,而非可信任的重用(类似于{ name, filePath }中的token_map)。在导入前确认获胜的ambiguousWith与备选组件中哪个更适合当前上下文(错误的重用会导致隐性视觉bug),然后将确认的组件记录到映射文件中,以便下次运行时能确定选择。当选择明确时该字段不存在。candidate - 将每个条目的(已解析的变体/布尔/文本值)关联到重用组件——每个实例对应一个元素,拥有独立属性。
instances[].props - :Figma组件轴中没有对应属性的部分(如前置图标、
candidate.unmatchedProps标记、激活状态)→ 作为组件扩展的待办事项列出,绝不要用临时标记伪造。required - :按照项目风格全新构建。对于重复出现的未映射组件(
unmapped),基于其第一个实例的子树构建;如果该子树返回instanceCount > 1/deduped,则针对truncated调用一次instances[0].nodeId——不要凭视觉重建重复组件。get_design_context - 当你输出组件的自身定义(其属性类型,而非仅渲染它)时,对组件/实例调用会返回完整的属性API——每个VARIANT选项以及每个BOOLEAN/TEXT/INSTANCE_SWAP属性及其默认值——确保属性空间基于事实,而非从你恰好看到的实例中推断。
get_component_api
-
→ 每个Figma变量与项目令牌关联,包含
token_map+status+ref。文档的共享填充样式(单一纯色样式——预变量文件的令牌机制)以相同方式关联,标记为matchedBy。source: 'style'- 已映射:引用(如
candidate.ref、bg-primary-500)——绝不要使用var(--color-primary-500)解析的原始十六进制/像素值。颜色的get_design_context(值已偏移):可以使用,但要标记不匹配。matchedBy: ['name'] - (多个项目令牌共享完全相同的值,名称无法区分):一组有限的需要验证的选项——根据上下文选择语义正确的令牌(或保留值并标记缺口),绝不要将其视为已确认的重用。
candidate.ambiguousWith - 对于变量很少或没有变量的文档(大多数真实场景文件),自身的
get_design_context映射是备选方案: payload中任何与项目令牌值完全匹配的原始颜色都会在其中标注(如projectTokens)。在硬编码十六进制值前,先查找该映射,当语义符合上下文时输出{ "#6266F0": { ref, name, matchedBy: ["value"] } }。ref表示该条目是基于值相等的无名称匹配证据——一个需要验证的假设,而非已解决的绑定:带有matchedBy: ["value"]的条目列出了具有相同值的令牌,需根据含义选择;语义错误的令牌比原始值更糟(此时应保留原始值并记录缺口),且绑定的Figma变量始终优先于原始值匹配。candidates - (Tailwind内置刻度步骤,如
framework-builtin、spacing/4、line-height/7):包含weight/Bold——组合实用类(如builtin: { scale, step }/p-4、gap-4、leading-7),不要使用任意值font-bold。这不属于缺口。p-[16px] - :使用该值但需指出缺口(建议将其添加到令牌源);不要静默硬编码。
unmapped - (
figmaModes,文件的主题轴位于{ Light: …, Dark: … }):令牌依赖主题——themedCollections仅为默认模式,而非全部内容。已映射:输出figmaValue并确认项目令牌本身会随主题切换(如candidate.ref/.dark/[data-theme]/prefers-color-scheme规则);如果项目仅定义了一个值,则将其他模式的值关联到该机制或指出主题缺口。未映射:默认模式为基础,其他模式遵循项目的暗色模式机制(如dark:变体 /dark:)。未使用原生模式编码的主题——配对集合或名称组(如prefers-color-scheme+Color/Light/*,受计划限制的变通方案)——采用相同处理方式。Color/Dark/*
- 已映射:引用
-
导出无法通过事实工具传递的资源——标志、照片、图标没有像素,否则会渲染为灰色块。对填充节点使用
IMAGE(原始资源,而非裁剪后的重渲染),先对图标使用save_image_fills(重用经过整理的icon_map文件),仅对合成外观使用.svg。 → 完整的资源/图标/SVG/颜色约定工作流程:get_screenshot。references/assets-and-icons.md
然后根据检测到的技术栈生成代码(配置文件来自 / ;无需自行调用):组合重用的组件,包装未映射的部分,并为颜色/间距/圆角/排版应用令牌引用。
component_maptoken_mapanalyze_projectKeep code in sync as the design changes
随设计变更保持代码同步
Codegen is rarely one-shot — the design keeps moving. To make the second pass an incremental edit
instead of a regeneration:
- After you generate, on the section/component
design_diffsaves a baseline (itsnodeId) underget_design_context. Committing that file lets teammates share the baseline; the tool never touches git..figwright/snapshots/ - When asked to re-sync ("the design changed, update the component"), the same
design_diffagain: it returns the per-node, per-property delta —nodeId/added/removednodes with resolved values (a fill, a padding, a text string, a token rebind), each with a readablechanged(path). Edit only the code those nodes map to; don't regenerate the screen. Ground each changed value the usual way (it's aCard / Header / Titleslice), thenget_design_contextwithdesign_diffto accept the new design as the baseline.update: true - Scope it by the same unit you coded from.
nodeIdmeans the design is untouched since the baseline — nothing to do.no-changes
代码生成很少是一次性的——设计会持续更新。为了让第二次迭代成为增量编辑而非重新生成:
- 生成代码后,对区块/组件的调用
nodeId,将基线(其design_diff)保存到get_design_context目录下。提交该文件可让团队成员共享基线;工具绝不会触碰git。.figwright/snapshots/ - 当要求重新同步时(“设计已变更,更新组件”),再次对相同的调用
nodeId:它会返回每个节点、每个属性的差异——design_diff/added/removed节点及已解析的值(如填充、内边距、文本字符串、令牌重新绑定),每个都带有可读的changed(如path)。仅编辑这些节点映射到的代码;不要重新生成整个页面。按照常规方式验证每个变更的值(这是Card / Header / Title的切片),然后调用get_design_context并设置design_diff以接受新设计作为基线。update: true - 按照你编码时使用的相同单元限定范围。
nodeId表示自基线以来设计未被修改——无需执行任何操作。no-changes
Record verified mappings (so the next run reuses, not re-guesses)
记录已验证的映射关系(让下次运行重用而非重新猜测)
The joins re-derive from scratch every run. A mapping you confirmed — reused a component and it
rendered right, resolved an ambiguous colour to the semantically correct token — is worth recording
so the next run treats it as ground truth instead of re-guessing. Two append-only map files, each read
back by its join as highest authority:
-
— rows
docs/figma-component-map.md(or| FigmaName | code/path |).FigmaName -> paththen returns that component ascomponent_map, confidence 1.source: 'map-file' -
— rows
docs/figma-token-map.md.| FigmaName | ref |returns it astoken_map, confidence 1. ThematchedBy: ['map-file']is what you'd emit — a utility (ref), abg-primary-500, or the bare token name.var(--color-primary-500) -
A recorded row OVERRIDES the fuzzy join on every future run — so record proof, not a pick. The gate is your own verify step (§ Responsive & verify): only after you rendered the result and it matched the Figma node do you record the mapping you proved. A wrong row doesn't fail loudly — it silently mis-maps that component/token in every future generation until a human notices, which is worse than no record at all. If you're not certain, don't record it; a re-guess next run is recoverable, a confidently-wrong recorded row is not.
-
Record only the mappings the join was unsure of — a/
lowcomponent match you confirmed, anmediumcomponent you built (record its new file), or a token that came backunmapped/ambiguousWith/matchedBy: ['value']and you resolved by meaning. Skip the already-unmappeddeterministic matches; they re-derive correctly and a row for them is just noise.high -
These files are committed project docs — treat a row like a line of code you're asserting is correct, not a scratch note. One figma name → one target per row; keep them reviewable.
-
Keep the files healthy. When/
component_mapreporttoken_map(a recorded target that no longer resolves — the file/token was renamed or deleted), the join has already degraded to the fuzzy result; fix that row to the new target or delete it.staleOverrides
每次运行都会重新推导关联关系。你已确认的映射——重用组件且渲染正确,将模糊的颜色解析为语义正确的令牌——值得记录,以便下次运行将其视为事实依据而非重新猜测。两个仅追加的映射文件,每个都会被其关联工具作为最高优先级读取:
-
—— 行格式为
docs/figma-component-map.md(或| FigmaName | code/path |)。FigmaName -> path会将该组件返回为component_map,置信度为1。source: 'map-file' -
—— 行格式为
docs/figma-token-map.md。| FigmaName | ref |会将其返回为token_map,置信度为1。matchedBy: ['map-file']是你要输出的内容——实用类(如ref)、bg-primary-500或令牌名称。var(--color-primary-500) -
已记录的行会覆盖未来每次运行的模糊关联——因此要记录已验证的结果,而非随意选择。 门槛是你自己的验证步骤(§ 响应式设计与验证):只有在你渲染结果并确认其与Figma节点匹配后,才记录你已验证的映射。错误的行不会明显报错——它会在未来每次生成中静默错误映射该组件/令牌,直到有人发现,这比没有记录更糟糕。如果你不确定,不要记录;下次运行重新猜测是可恢复的,但自信记录的错误行则不然。
-
仅记录关联工具不确定的映射——你已确认的/
low组件匹配、你构建的medium组件(记录其新文件),或者返回unmapped/ambiguousWith/matchedBy: ['value']且你已根据含义解决的令牌。跳过已确定的unmapped匹配;它们会被正确重新推导,记录这些行只是冗余信息。high -
这些文件是已提交的项目文档——将每一行视为你断言正确的代码,而非临时笔记。每个Figma名称对应一个目标;保持文件可审阅。
-
保持文件有效。当/
component_map报告token_map(已记录的目标无法解析——文件/令牌已重命名或删除)时,关联工具已降级为模糊结果;将该行修复为新目标或删除它。staleOverrides
Responsive & verify
响应式设计与验证
- Responsive by default — root is , never the artboard's fixed width; ground breakpoints from the file's other-width frames. →
w-full.references/responsive.md - Verify visually before you call it done — render with the project's toolchain, screenshot at the
design's viewport, diff against the Figma node, fix at the source.
→ .
references/verify.md
- 默认支持响应式 —— 根元素为,绝不要使用画板的固定宽度;从文件的其他宽度框架中确定断点。→
w-full。references/responsive.md - 完成前先进行视觉验证 —— 使用项目的工具链渲染,在设计的视口截图,与Figma节点对比差异,从源头修复。
→ 。
references/verify.md
Motion (animation)
动效(动画)
When (full detail) tags a node with a summary — applied
animation-style presets, animated property fields, a timeline duration — carry it into the project's
animation mechanism (CSS / , Framer Motion, GSAP, Vue ) instead
of emitting a static component. returns the full keyframe detail when the summary
isn't enough. Dropping a frame's animation is a fidelity miss, the same class as dropping a shadow.
→ .
get_design_contextmotion@keyframestransition<transition>get_node_motionreferences/motion.md当(完整详情)为节点标记摘要时——应用的动画样式预设、动画属性字段、时间线时长——将其转换为项目的动画机制(如CSS / 、Framer Motion、GSAP、Vue ),而非输出静态组件。当摘要不够详细时,会返回完整的关键帧详情。忽略框架的动画是保真度缺失,与忽略阴影属于同一类问题。
→ 。
get_design_contextmotion@keyframestransition<transition>get_node_motionreferences/motion.mdRules
规则
- Ground every section — never eyeball a value off the screenshot. Every px size, colour,
font-size, radius, and spacing comes from , for every section. The screenshot is visual intent only; guessing "the easy sections" is the cardinal miss. On a page too big to ground at once, scope by section
get_design_context— never depth-cap the whole page, never retry an oversized call.nodeId - Reuse beats regenerate. A /
highmediumcandidate must be imported and used.component_map - Reference tokens, not literals. Emit a mapped variable's ; reserve raw values for
refgaps, and surface those gaps rather than burying them.unmapped - Carry every visual property, don't drop fidelity. Effects, per-side borders + , per-corner radius, blend mode, masks, gradients, image
strokeAlign, and auto-layout/grid spacing are all in the context — translate each (the catalog is inscaleMode). Dropping any is a grounding miss, not a simplification.references/grounding.md - Export visual assets, don't fake them. A grey box or a hand-typed wordmark is a miss.
- Match the project, not a house style. Mirror the existing import style, file layout, and naming.
- Render and verify before you call it done. (See .)
references/verify.md - Never write a config file or wizard prompt; everything is inferred from the project + the tools.
- 每个部分都基于事实——绝不要从截图中目测取值。 每个像素尺寸、颜色、字体大小、圆角和间距都来自,覆盖所有部分。截图仅用于视觉参考;猜测“简单部分”是最严重的错误。对于单次调用无法处理的大型页面,按区块
get_design_context划分范围——绝不要限制整个页面的深度,绝不要重试超出范围的调用。nodeId - 重用优先于重新生成。 中的
component_map/high候选组件必须被导入并使用。medium - 引用令牌,而非字面量。 输出已映射变量的;仅为
ref缺口保留原始值,并指出这些缺口而非隐藏它们。unmapped - 保留所有视觉属性,不要降低保真度。 效果、单边边框 + 、圆角半径、混合模式、遮罩、渐变、图片
strokeAlign以及自动布局/网格间距都包含在上下文中——逐一转换(目录位于scaleMode)。忽略任何一项都是基于事实的工具使用失误,而非简化。references/grounding.md - 导出视觉资源,不要伪造。 灰色框或手动输入的标志是失误。
- 匹配项目风格,而非通用风格。 镜像现有的导入风格、文件布局和命名方式。
- 完成前先渲染并验证。(参见。)
references/verify.md - 绝不要编写配置文件或向导提示;所有内容都从项目和工具中推断。