← FigmaCONTENT HISTORY

Update to Figma

Snapshot Sep 30, 2026 · 22:44 UTC · version 15.0.0

Collection source: not recorded for this historical snapshot.

WHAT CHANGED · RULE-BASED ANALYSIS

First saved snapshot

No earlier snapshot is available to establish a change.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "name": "figma-code-connect",
  "description": "Creates and maintains Figma Code Connect template files that map Figma components to code snippets. Use when the user mentions Code Connect, Figma component mapping, design-to-code translation, or asks to create/update .figma.ts or .figma.js files.",
  "included_files": [
    {
      "relative_path": "references/advanced-patterns.md",
      "size_in_bytes": 10069
    },
    {
      "relative_path": "references/api.md",
      "size_in_bytes": 23396
    }
  ],
  "skill_md_contents": "---\nname: figma-code-connect\ndescription: Creates and maintains Figma Code Connect template files that map Figma components to code snippets. Use when the user mentions Code Connect, Figma component mapping, design-to-code translation, or asks to create/update .figma.ts or .figma.js files.\ndisable-model-invocation: false\n---\n\n# Code Connect\n\n## Overview\n\nCreate Code Connect template files (`.figma.ts`) that map Figma components to code snippets. Given a Figma URL, follow the steps below to create a template.\n\n> **You write `.figma.ts` template files ONLY — never `.figma.tsx`.** This skill produces *parserless templates*: a `.figma.ts` file whose default export uses a `` figma.code`...` `` tagged template. Do **NOT** write a `.figma.tsx` file and do **NOT** use `figma.connect()` — that is the separate **parser-based** Code Connect format (published a different way) and is the **wrong artifact** for this skill; output written as `.figma.tsx` is rejected outright. If a `.figma.tsx` already exists for a component, leave it untouched and add your `.figma.ts` template alongside it. A capable model may be tempted to reach for the more familiar `.figma.tsx` / `figma.connect()` pattern from memory — resist it; here the correct output is **always** `.figma.ts` + `figma.code`.\n\n## Prerequisites\n\n- **Figma MCP server must be connected** — verify that Figma MCP tools (e.g., `get_code_connect_suggestions`) are available before proceeding. If not, guide the user to enable the Figma MCP server and restart their MCP client.\n- **Components must be published** — Code Connect only works with components published to a Figma team library. If a component is not published, inform the user and stop.\n- **Organization or Enterprise plan required** — Code Connect is not available on Free or Professional plans.\n- **URL must include `node-id`** — the Figma URL must contain the `node-id` query parameter.\n- **TypeScript types** — for editor autocomplete and type checking in `.figma.ts` files `@figma/code-connect/figma-types` must be added to `types` in `tsconfig.json`:\n  ```json\n  {\n    \"compilerOptions\": {\n      \"types\": [\"@figma/code-connect/figma-types\"]\n    }\n  }\n  ```\n\n## Step 1: Parse the Figma URL\n\nExtract `fileKey` and `nodeId` from the URL:\n\n| URL Format | fileKey | nodeId |\n|---|---|---|\n| `figma.com/design/:fileKey/:name?node-id=X-Y` | `:fileKey` | `X-Y` → `X:Y` |\n| `figma.com/file/:fileKey/:name?node-id=X-Y` | `:fileKey` | `X-Y` → `X:Y` |\n| `figma.com/design/:fileKey/branch/:branchKey/:name` | use `:branchKey` | from `node-id` param |\n\nAlways convert `nodeId` hyphens to colons: `1234-5678` → `1234:5678`.\n\n**Worked example:**\n\nGiven: `https://www.figma.com/design/QiEF6w564ggoW8ftcLvdcu/MyDesignSystem?node-id=4185-3778`\n- `fileKey` = `QiEF6w564ggoW8ftcLvdcu`\n- `nodeId` = `4185-3778` → `4185:3778`\n\n## Step 2: Discover Unmapped Components\n\nThe user may provide a URL pointing to a frame, instance, or variant — not necessarily a component set or standalone component. Call the MCP tool `get_code_connect_suggestions` with:\n- `fileKey` — from Step 1\n- `nodeId` — from Step 1 (colons format)\n- `excludeMappingPrompt` — `true` (returns a lightweight list of unmapped components)\n\nThis tool identifies published components in the selection that don't yet have Code Connect mappings.\n\n**Handle the response:**\n\n- **\"No published components found in this selection\"** — the node contains no published components. Inform the user they need to publish the component to a team library in Figma first, then stop.\n- **\"All component instances in this selection are already connected to code via Code Connect\"** — everything is already mapped. Inform the user and stop.\n- **Normal response with component list** — extract the `mainComponentNodeId` for each returned component. Use these resolved node IDs (not the original from the URL) for all subsequent steps. If multiple components are returned (e.g. the user selected a frame containing several different component instances), repeat Steps 3–6 for each one.\n\n## Step 3: Fetch Component Properties\n\nCall the MCP tool `get_context_for_code_connect` with:\n- `fileKey` — from Step 1\n- `nodeId` — the resolved `mainComponentNodeId` from Step 2\n- `clientFrameworks` — determine from `figma.config.json` `parser` field (e.g. `\"react\"` → `[\"react\"]`)\n- `clientLanguages` — infer from project file extensions (e.g. TypeScript project → `[\"typescript\"]`, JavaScript → `[\"javascript\"]`)\n\nFor multiple components, call the tool once per node ID.\n\nThe response contains the Figma component's **property definitions** — note each property's name and type:\n- **TEXT** — text content (labels, titles, placeholders)\n- **BOOLEAN** — toggles (show/hide icon, disabled state)\n- **VARIANT** — enum options (size, variant, state)\n- **INSTANCE_SWAP** — swappable nested instances tied to a specific component (icon, avatar)\n- **SLOT** — flexible content regions (freeform layout, mixed children); use `getSlot()` in templates (not the same as INSTANCE_SWAP)\n\nSave this property list — you will use it in Step 5 to write the template.\n\n## Step 4: Identify the Code Component\n\nIf the user did not specify which code component to connect:\n\n1. Check `figma.config.json` for `paths` and `importPaths` to find where components live\n2. Search the codebase for a component matching the Figma component name. Check common directories (`src/components/`, `components/`, `lib/ui/`, `app/components/`) if `figma.config.json` doesn't specify paths\n3. Read candidate files and compare their props interface against the Figma properties from Step 3 — look for matching variant types, size options, boolean flags, and slot props\n4. If multiple candidates match, pick the one with the closest prop-interface match and explain your reasoning to the user\n5. If no match is found, show the 2 closest candidates and ask the user to confirm or provide the correct path\n\n**Confirm with the user** before proceeding to Step 5. Present the match: which code component you found, where it lives, and why it matches (prop correspondence, naming, purpose).\n\nRead `figma.config.json` for import path aliases — the `importPaths` section maps glob patterns to import specifiers, and the `paths` section maps those specifiers to directories.\n\nRead the code component's source to understand its props interface — this informs how to map Figma properties to code props in Step 5.\n\n## Step 5: Create the Template File (.figma.ts)\n\n### File location\n\nPlace the file alongside existing Code Connect files. Check `figma.config.json` `include` patterns for the correct directory. **Name it `ComponentName.figma.ts` — never `ComponentName.figma.tsx`.** The `.figma.tsx` extension is the parser-based format; do not create one or modify an existing one.\n\n### Template structure\n\nEvery template file follows this structure:\n\n```ts\n// url=https://www.figma.com/file/{fileKey}/{fileName}?node-id={nodeId}\n// source={path to code component from Step 4}\n// component={code component name from Step 4}\nimport figma from 'figma'\nconst instance = figma.selectedInstance\n\n// Extract properties from the Figma component (see property mapping below)\n// ...\n\nexport default {\n  example: figma.code`<Component ... />`,       // Required: code snippet\n  imports: ['import { Component } from \"...\"'], // Optional: import statements\n  id: 'component-name',                         // Required: unique identifier\n  metadata: {                                    // Optional\n    nestable: true,                              // true = inline in parent, false = show as pill\n    props: {}                                    // data accessible to parent templates\n  }\n}\n```\n\n### Property mapping\n\nUse the property list from Step 3 to extract values. For each Figma property type, use the corresponding method:\n\n| Figma Property Type | Template Method | When to Use |\n|---|---|---|\n| TEXT | `instance.getString('Name')` | Labels, titles, placeholder text |\n| BOOLEAN | `instance.getBoolean('Name', { true: ..., false: ... })` | Toggle visibility, conditional props |\n| VARIANT | `instance.getEnum('Name', { 'FigmaVal': 'codeVal' })` | Size, variant, state enums |\n| INSTANCE_SWAP | `instance.getInstanceSwap('Name')` | Swapped instance for a fixed component slot (then `hasCodeConnect()` / `executeTemplate()`) - do not confuse with the SLOT property below |\n| SLOT | `instance.getSlot('Name')` | Freeform slot content only when the Figma property type is **SLOT** \n| (child layer) | `instance.findInstance('LayerName')` | Named child instances without a property |\n| (text layer) | `instance.findText('LayerName')` → `.textContent` | Text content from named layers |\n\n**TEXT** — get the string value directly:\n```ts\nconst label = instance.getString('Label')\n```\n\n**VARIANT** — map Figma enum values to code values:\n```ts\nconst variant = instance.getEnum('Variant', {\n  'Primary': 'primary',\n  'Secondary': 'secondary',\n})\n\nconst size = instance.getEnum('Size', {\n  'Small': 'sm',\n  'Medium': 'md',\n  'Large': 'lg',\n})\n```\n\n**BOOLEAN** — simple boolean or mapped to values:\n```ts\n// Simple boolean\nconst disabled = instance.getBoolean('Disabled')\n\n// Mapped to code values (e.g. when the code prop is an enum, not a boolean)\nconst size = instance.getBoolean('Show Label', { true: 'large', false: 'small' })\n```\n\n**Map Figma properties to code props where there's a valid correspondence.** Figma properties and code props don't always line up 1:1 — some Figma properties map directly (by name, or via the API methods above), others have no code equivalent. Where a mapping exists, use it; where none fits, omit the Figma property rather than invent a code prop. Never emit an attribute whose name doesn't appear in the code component's `Props` interface.\n\n### Exhaustive variant handling\n\nWhen a VARIANT property has multiple possible values, the `getEnum` mapping **must list every value** returned by `get_context_for_code_connect`. Don't omit values — an unmapped value silently returns `undefined`, producing broken output.\n\n```ts\n// WRONG — omits 'Warning', which will render as undefined\nconst status = instance.getEnum('Status', {\n  'Success': 'success',\n  'Error': 'error',\n})\n\n// CORRECT — every value is mapped\nconst status = instance.getEnum('Status', {\n  'Success': 'success',\n  'Error': 'error',\n  'Warning': 'warning',\n  'Info': 'info',\n})\n```\n\nWhen **two or more VARIANT properties combine** to produce different code output, generate exhaustive conditional branches. For example, 2 variants × 2 values = 4 branches:\n\n```ts\nconst type = instance.getEnum('Type', { 'Filled': 'filled', 'Outlined': 'outlined' })\nconst status = instance.getEnum('Status', { 'Success': 'success', 'Error': 'error' })\n\nlet colorClass\nif (type === 'filled' && status === 'success') {\n  colorClass = 'bg-green-500 text-white'\n} else if (type === 'filled' && status === 'error') {\n  colorClass = 'bg-red-500 text-white'\n} else if (type === 'outlined' && status === 'success') {\n  colorClass = 'bg-transparent border-green-500'\n} else if (type === 'outlined' && status === 'error') {\n  colorClass = 'bg-transparent border-red-500'\n}\n```\n\nIf the combinations produce **repetitive** output (e.g., `Size` doesn't change the snippet structure — it's just passed through as a prop), a single `getEnum` mapping per variant is sufficient — no need for cross-product branches.\n\n**INSTANCE_SWAP** — access swappable component instances:\n```ts\nconst icon = instance.getInstanceSwap('Icon')\nlet iconCode\nif (icon && icon.type === 'INSTANCE') {\n  iconCode = icon.executeTemplate().example\n}\n```\n\n**SLOT** — `getSlot(propName)` is only valid when the Figma component property reported in Step 3 has type **`SLOT`**. Do not use `getSlot()` for **INSTANCE_SWAP** properties (those use `getInstanceSwap()`). Slots are explicit “content regions” in the component definition, not generic nested instances.\n\n- **Signature:** `getSlot(propName: string): ResultSection[] | undefined`\n```ts\n// Figma property \"Content\" must be type SLOT in component properties\nconst content = instance.getSlot('Content')\n\nexport default {\n  example: figma.code`<Card>${content}</Card>`,\n  // ...\n}\n```\n\n### Interpolation in tagged templates\n\nWhen interpolating values in tagged templates, use the correct wrapping:\n- **String values** (`getString`, `getEnum`, `textContent`): wrap in quotes → `variant=\"${variant}\"`\n- **Instance/section values** (`executeTemplate().example`): wrap in braces → `icon={${iconCode}}`\n- **Slot sections** (`getSlot()` result — `ResultSection[] | undefined`): interpolate directly inside `` figma.code`...` `` (same shape as nested snippet sections), e.g. `` figma.code`<Select>${content}</Select>` `` — do not treat as a plain string\n- **Boolean bare props**: use conditional → `${disabled ? 'disabled' : ''}`\n\n### Finding descendant layers\n\nWhen you need to access children that aren't exposed as component properties:\n\n| Method | Use when |\n|---|---|\n| `instance.getInstanceSwap('PropName')` | Figma property type is **INSTANCE_SWAP** (fixed swapped instance) |\n| `instance.getSlot('PropName')` | Figma property type is **SLOT** (freeform content region) |\n| `instance.findInstance('LayerName')` | You know the child layer name (no component property) |\n| `instance.findText('LayerName')` → `.textContent` | You need text content from a named text layer |\n| `instance.findConnectedInstance('id')` | You know the child's Code Connect `id` |\n| `instance.findConnectedInstances(fn)` | You need multiple connected children matching a filter |\n| `instance.findLayers(fn)` | You need any layers (text + instances) matching a filter |\n\n### Nested configurable instances\n\nA component may contain child instances that are **not exposed as component properties** (no INSTANCE_SWAP) but are still **independently configurable** — they have their own variants, properties, or swap slots. These must be resolved dynamically, not hardcoded.\n\n1. **Check whether the child already has a Code Connect template** — use `get_code_connect_suggestions` or check existing `.figma.ts` files in the project.\n2. **If no template exists, create one** for the child so it renders correctly both standalone and when nested.\n3. **Reference the child from the parent** using `findInstance()` or `findConnectedInstance()`, then call `executeTemplate()`.\n\n```ts\n// Parent template — the Badge child isn't a prop, but it's configurable\nconst badge = instance.findInstance('Status Badge')\nlet badgeCode\nif (badge && badge.type === 'INSTANCE') {\n  badgeCode = badge.executeTemplate().example\n}\n\nexport default {\n  example: figma.code`<Card>${badgeCode}</Card>`,\n  // ...\n}\n```\n\nThis applies to icons, badges, labels, and any other nested instance that is configurable by itself — always connect them and render dynamically, never hardcode their content.\n\n### Nested component example\n\nFor multi-level nested components or metadata prop passing between templates, see [advanced-patterns.md](references/advanced-patterns.md).\n\n```ts\nconst icon = instance.getInstanceSwap('Icon')\nlet iconSnippet\nif (icon && icon.type === 'INSTANCE') {\n  iconSnippet = icon.executeTemplate().example\n}\n\nexport default {\n  example: figma.code`<Button ${iconSnippet ? figma.code`icon={${iconSnippet}}` : ''}>${label}</Button>`,\n  // ...\n}\n```\n\n### Conditional props\n\n```ts\nconst variant = instance.getEnum('Variant', { 'Primary': 'primary', 'Secondary': 'secondary' })\nconst disabled = instance.getBoolean('Disabled')\n\nexport default {\n  example: figma.code`\n    <Button\n      variant=\"${variant}\"\n      ${disabled ? 'disabled' : ''}\n    >\n      ${label}\n    </Button>\n  `,\n  // ...\n}\n```\n\n## Step 6: Validate\n\nRead back the `.figma.ts` file and review it against the following:\n\n- **Correct file type & format (check this FIRST)** — the file is `ComponentName.figma.ts` (NOT `.figma.tsx`), and its default export is a parserless template using a `` figma.code`...` `` tagged template. It must NOT use `figma.connect()` (the parser-based format). If you wrote `.figma.tsx` or `figma.connect()`, discard it and rewrite as a `.figma.ts` `figma.code` template.\n- **Property coverage** — every Figma property from Step 3 should be accounted for in the template. Flag any that are missing and ask the user if they were intentionally omitted.\n- **Valid, correctly typed code** — all emitted code must be valid and correctly typed against the code component's `Props` interface. Never make up component properties — if a Figma property has no corresponding code prop, omit it rather than invent one.\n- **No hardcoded children** — verify that every INSTANCE_SWAP property and child component slot uses the dynamic APIs (`getInstanceSwap()`, `findInstance()`, `findConnectedInstance()`, etc.) with `executeTemplate()`. No slot should contain hardcoded component content.\n- **Rules and Pitfalls** — check for the common mistakes listed below (string concatenation of template results, unnecessary `hasCodeConnect()` guards, missing `type === 'INSTANCE'` checks, etc.)\n- **Interpolation wrapping** — strings (`getString`, `getEnum`, `textContent`) wrapped in quotes, instance/section values (`executeTemplate().example`) wrapped in braces, slot sections (`getSlot`) interpolated as snippet sections inside `` figma.code`...` ``, booleans using conditionals\n\nIf anything looks uncertain, consult [api.md](references/api.md) for API details and [advanced-patterns.md](references/advanced-patterns.md) for complex nesting.\n\n## Inline Quick Reference\n\n### `instance.*` Methods\n\n| Method | Signature | Returns |\n|---|---|---|\n| `getString` | `(propName: string)` | `string` |\n| `getBoolean` | `(propName: string, mapping?: { true: any, false: any })` | `boolean \\| any` |\n| `getEnum` | `(propName: string, mapping: { [figmaVal]: codeVal })` | `any` |\n| `getInstanceSwap` | `(propName: string)` | `InstanceHandle \\| null` |\n| `getSlot` | `(propName: string)` | `ResultSection[] \\| undefined` |\n| `getPropertyValue` | `(propName: string)` | `string \\| boolean` |\n| `findInstance` | `(layerName: string, opts?: SelectorOptions)` | `InstanceHandle \\| ErrorHandle` |\n| `findText` | `(layerName: string, opts?: SelectorOptions)` | `TextHandle \\| ErrorHandle` |\n| `findConnectedInstance` | `(codeConnectId: string, opts?: SelectorOptions)` | `InstanceHandle \\| ErrorHandle` |\n| `findConnectedInstances` | `(selector: (node) => boolean, opts?: SelectorOptions)` | `InstanceHandle[]` |\n| `findLayers` | `(selector: (node) => boolean, opts?: SelectorOptions)` | `(InstanceHandle \\| TextHandle)[]` |\n\n### InstanceHandle Methods\n\n| Method | Returns |\n|---|---|\n| `hasCodeConnect()` | `boolean` |\n| `executeTemplate()` | `{ example: ResultSection[], metadata: Metadata }` |\n| `codeConnectId()` | `string \\| null` |\n\n### TextHandle Properties\n\n| Property | Type |\n|---|---|\n| `.textContent` | `string` |\n| `.name` | `string` |\n\n### SelectorOptions\n\n```ts\n{ path?: string[], traverseInstances?: boolean }\n```\n\n- `traverseInstances: true` — required when the target lives inside another nested instance. Without it, `findInstance`/`findText` only search the current instance's own layers and stop at nested instance boundaries.\n- `path: string[]` — disambiguates when multiple descendants share the same layer name. Lists parent layer names that must appear on the path to the target.\n\n**Examples:**\n\n```ts\n// Layer hierarchy:\n//   A > C (instance) > \"mychild\"\n// \"mychild\" sits inside nested instance C, so plain findInstance returns ErrorHandle.\ninstance.findInstance('mychild', { traverseInstances: true })\n\n// Layer hierarchy:\n//   A > C (instance) > \"mychild\"\n//   A > D (instance) > \"mychild\"\n// Two \"mychild\" layers exist — use path to pick the one under C.\ninstance.findInstance('mychild', { traverseInstances: true, path: ['C'] })\n```\n\n**When to reach into a nested instance from a parent template:** only when the parent code component (from Step 4) takes the nested layer as a prop value itself (e.g. `<C show={<B />} />` — A forwards B into C). If the parent just composes C and C renders B internally, resolve C with `executeTemplate()` and let C's own template handle B — don't duplicate B's rendering at the parent level.\n\n### Export Structure\n\n```ts\nexport default {\n  example: figma.code`...`,                      // Required: ResultSection[]\n  id: 'component-name',                         // Required: string\n  imports: ['import { X } from \"...\"'],          // Optional: string[]\n  metadata: { nestable: true, props: {} }        // Optional\n}\n```\n\n## Rules and Pitfalls\n\n1. **Never string-concatenate template results.** `executeTemplate().example` is a `ResultSection[]` object, not a string. Using `+` or `.join()` produces `[object Object]`. Always interpolate inside tagged templates: `` figma.code`${snippet1}${snippet2}` ``\n\n2. **Do not use `hasCodeConnect()` guards.** Call `executeTemplate()` directly on any instance after a `type === 'INSTANCE'` check. The runtime handles instances without Code Connect automatically.\n\n   ```ts\n   // WRONG — hasCodeConnect() gate drops non-CC instances\n   if (icon && icon.type === 'INSTANCE' && icon.hasCodeConnect()) {\n     iconCode = icon.executeTemplate().example\n   }\n\n   // CORRECT — let the runtime handle all instances\n   if (icon && icon.type === 'INSTANCE') {\n     iconCode = icon.executeTemplate().example\n   }\n   ```\n\n3. **Check `type === 'INSTANCE'` before calling `executeTemplate()`.** `findInstance()`, `findConnectedInstance()`, and `findText()` return an `ErrorHandle` (truthy, but not a real node) on failure — not `null`. Always add a type check to avoid crashes: `if (child && child.type === 'INSTANCE') { ... }`\n\n4. **Prefer `getInstanceSwap()` over `findInstance()`** when a component property exists for the slot. `findInstance('Star Icon')` breaks when the icon is swapped to a different name; `getInstanceSwap('Icon')` always works regardless of which instance is in the slot.\n\n5. **Use `getSlot()` only when the Figma property type is `SLOT`.** For **INSTANCE_SWAP** props, use `getInstanceSwap()` (returns an `InstanceHandle`). `getSlot()` returns structured slot sections, not instances — never call `executeTemplate()` on its return value.\n\n6. **Property names are case-sensitive** and must exactly match what `get_context_for_code_connect` returns.\n\n7. **Handle multiple template arrays correctly.** When iterating over children, set each result in a separate variable and interpolate them individually — do not use `.map().join()`:\n   ```ts\n   // Wrong:\n   items.map(n => n.executeTemplate().example).join('\\n')\n\n   // Correct — use separate variables:\n   const child1 = items[0]?.executeTemplate().example\n   const child2 = items[1]?.executeTemplate().example\n   export default { example: figma.code`${child1}${child2}` }\n   ```\n\n7. **Never hardcode slot or children content.** Always resolve child instances dynamically — use `getInstanceSwap()` for INSTANCE_SWAP properties, `findInstance()`/`findConnectedInstance()` for direct children — and render them via `executeTemplate()`. Never construct JSX from a layer name (e.g., `<StarIcon />`) or guess import paths. If an instance has no Code Connect, omit it — do not add a hardcoded fallback.\n\n   ```ts\n   // WRONG — hardcodes the icon from its layer name\n   example: figma.code`<Button icon={<StarIcon />}>Submit</Button>`\n\n   // CORRECT — resolves dynamically, works for any swapped icon\n   const icon = instance.findInstance('Icon')\n   let iconCode\n   if (icon && icon.type === 'INSTANCE') {\n     iconCode = icon.executeTemplate().example\n   }\n   example: figma.code`<Button${iconCode ? figma.code` icon={${iconCode}}` : ''}>...</Button>`\n   ```\n\n8. **Attempt to represent every Figma property via a code prop.** The code component's `Props` interface (from Step 4) is the authoritative list of attribute names. For each Figma property, figure out the right way to represent it using the API methods from Step 5 — direct name match, value transformation, or whatever fits. If no code prop fits at all, omit it — don't invent a prop name.\n\n## Complete Worked Example\n\nGiven URL: `https://figma.com/design/abc123/MyFile?node-id=42-100`\n\n**Step 1:** Parse the URL.\n- `fileKey` = `abc123`\n- `nodeId` = `42-100` → `42:100`\n\n**Step 2:** Call `get_code_connect_suggestions` with `fileKey: \"abc123\"`, `nodeId: \"42:100\"`, `excludeMappingPrompt: true`.\nResponse returns one component with `mainComponentNodeId: \"42:100\"`. If the response were empty, stop and inform the user. If multiple components were returned, repeat Steps 3–6 for each.\n\n**Step 3:** Call `get_context_for_code_connect` with `fileKey: \"abc123\"`, `nodeId: \"42:100\"` (from Step 2), `clientFrameworks: [\"react\"]`, `clientLanguages: [\"typescript\"]`.\n\nResponse includes properties:\n- Label (TEXT)\n- Variant (VARIANT): Primary, Secondary\n- Size (VARIANT): Small, Medium, Large\n- Disabled (BOOLEAN)\n- Has Icon (BOOLEAN)\n- Icon (INSTANCE_SWAP)\n\n**Step 4:** Search codebase → find `Button` component. Read its source to confirm props: `variant`, `size`, `disabled`, `icon`, `children`. Import path: `\"primitives\"`.\n\n**Step 5:** Create `src/figma/primitives/Button.figma.ts`:\n\n```ts\n// url=https://figma.com/design/abc123/MyFile?node-id=42-100\n// source=src/components/Button.tsx\n// component=Button\nimport figma from 'figma'\nconst instance = figma.selectedInstance\n\nconst label = instance.getString('Label')\nconst variant = instance.getEnum('Variant', {\n  'Primary': 'primary',\n  'Secondary': 'secondary',\n})\nconst size = instance.getEnum('Size', {\n  'Small': 'sm',\n  'Medium': 'md',\n  'Large': 'lg',\n})\nconst disabled = instance.getBoolean('Disabled')\nconst hasIcon = instance.getBoolean('Has Icon')\nconst icon = hasIcon ? instance.getInstanceSwap('Icon') : null\nlet iconCode\nif (icon && icon.type === 'INSTANCE') {\n  iconCode = icon.executeTemplate().example\n}\n\nexport default {\n  example: figma.code`\n    <Button\n      variant=\"${variant}\"\n      size=\"${size}\"\n      ${disabled ? 'disabled' : ''}\n      ${iconCode ? figma.code`icon={${iconCode}}` : ''}\n    >\n      ${label}\n    </Button>\n  `,\n  imports: ['import { Button } from \"primitives\"'],\n  id: 'button',\n  metadata: { nestable: true }\n}\n```\n\n**Step 6:** Read back file to verify syntax.\n\n## Additional Reference\n\nFor advanced patterns (multi-level nested components, `findConnectedInstances` filtering, metadata prop passing between parent/child templates):\n\n- [api.md](references/api.md) — Full Code Connect API reference\n- [advanced-patterns.md](references/advanced-patterns.md) — Advanced nesting, metadata props, and descendant patterns\n"
}

SHA-256: b19075967d9c60ed0a008094acd5c2a8e85a9fa206f14b38165918a987a9b7b0