Skip to main content

figma-code-connect

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.

설치로 이동

소스 정보

저장소
zhongjingyun/codex-plugins
최근 소스 활동
2026년 6월 10일 03:40
감지된 SKILL.md 언어
영어
스타
16
포크
2

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
3 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
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.
disable-model-invocation
false
# Code Connect ## Overview Create 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. > **Note:** This project may also contain parser-based `.figma.tsx` files (using `figma.connect()`, published via CLI). This skill covers **templates files only** — `.figma.ts` files that use the MCP tools to fetch component context from Figma. ## Prerequisites - **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. - **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. - **Organization or Enterprise plan required** — Code Connect is not available on Free or Professional plans. - **URL must include `node-id`** — the Figma URL must contain the `node-id` query parameter. - **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`: ```json { "compilerOptions": { "types": ["@figma/code-connect/figma-types"] } } ``` ## Step 1: Parse the Figma URL Extract `fileKey` and `nodeId` from the URL: | URL Format | fileKey | nodeId | |---|---|---| | `figma.com/design/:fileKey/:name?node-id=X-Y` | `:fileKey` | `X-Y` → `X:Y` | | `figma.com/file/:fileKey/:name?node-id=X-Y` | `:fileKey` | `X-Y` → `X:Y` | | `figma.com/design/:fileKey/branch/:branchKey/:name` | use `:branchKey` | from `node-id` param | Always convert `nodeId` hyphens to colons: `1234-5678` → `1234:5678`. **Worked example:** Given: `https://www.figma.com/design/QiEF6w564ggoW8ftcLvdcu/MyDesignSystem?node-id=4185-3778` - `fileKey` = `QiEF6w564ggoW8ftcLvdcu` - `nodeId` = `4185-3778` → `4185:3778` ## Step 2: Discover Unmapped Components The 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: - `fileKey` — from Step 1 - `nodeId` — from Step 1 (colons format) - `excludeMappingPrompt` — `true` (returns a lightweight list of unmapped components) This tool identifies published components in the selection that don't yet have Code Connect mappings. **Handle the response:** - **"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. - **"All component instances in this selection are already connected to code via Code Connect"** — everything is already mapped. Inform the user and stop. - **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. ## Step 3: Fetch Component Properties Call the MCP tool `get_context_for_code_connect` with: - `fileKey` — from Step 1 - `nodeId` — the resolved `mainComponentNodeId` from Step 2 - `clientFrameworks` — determine from `figma.config.json` `parser` field (e.g. `"react"` → `["react"]`) - `clientLanguages` — infer from project file extensions (e.g. TypeScript project → `["typescript"]`, JavaScript → `["javascript"]`) For multiple components, call the tool once per node ID. The response contains the Figma component's **property definitions** — note each property's name and type: - **TEXT** — text content (labels, titles, placeholders) - **BOOLEAN** — toggles (show/hide icon, disabled state) - **VARIANT** — enum options (size, variant, state) - **INSTANCE_SWAP** — swappable nested instances tied to a specific component (icon, avatar) - **SLOT** — flexible content regions (freeform layout, mixed children); use `getSlot()` in templates (not the same as INSTANCE_SWAP) Save this property list — you will use it in Step 5 to write the template. ## Step 4: Identify the Code Component If the user did not specify which code component to connect: 1. Check `figma.config.json` for `paths` and `importPaths` to find where components live 2. 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 3. 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 4. If multiple candidates match, pick the one with the closest prop-interface match and explain your reasoning to the user 5. If no match is found, show the 2 closest candidates and ask the user to confirm or provide the correct path **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). Read `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. Read the code component's source to understand its props interface — this informs how to map Figma properties to code props in Step 5. ## Step 5: Create the Template File (.figma.ts) ### File location Place the file alongside existing Code Connect templates (`.figma.tsx` or `.figma.ts` files). Check `figma.config.json` `include` patterns for the correct directory. Name it `ComponentName.figma.ts`. ### Template structure Every template file follows this structure: ```ts // 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 } } ``` ### Property mapping Use the property list from Step 3 to extract values. For each Figma property type, use the corresponding method: | Figma Property Type | Template Method | When to Use | |---|---|---| | TEXT | `instance.getString('Name')` | Labels, titles, placeholder text | | BOOLEAN | `instance.getBoolean('Name', { true: ..., false: ... })` | Toggle visibility, conditional props | | VARIANT | `instance.getEnum('Name', { 'FigmaVal': 'codeVal' })` | Size, variant, state enums | | INSTANCE_SWAP | `instance.getInstanceSwap('Name')` | Swapped instance for a fixed component slot (then `hasCodeConnect()` / `executeTemplate()`) - do not confuse with the SLOT property below | | SLOT | `instance.getSlot('Name')` | Freeform slot content only when the Figma property type is **SLOT** | (child layer) | `instance.findInstance('LayerName')` | Named child instances without a property | | (text layer) | `instance.findText('LayerName')` → `.textContent` | Text content from named layers | **TEXT** — get the string value directly: ```ts const label = instance.getString('Label') ``` **VARIANT** — map Figma enum values to code values: ```ts const variant = instance.getEnum('Variant', { 'Primary': 'primary', 'Secondary': 'secondary', }) const size = instance.getEnum('Size', { 'Small': 'sm', 'Medium': 'md', 'Large': 'lg', }) ``` **BOOLEAN** — simple boolean or mapped to values: ```ts // 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' }) ``` **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. ### Exhaustive variant handling When 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. ```ts // 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', }) ``` When **two or more VARIANT properties combine** to produce different code output, generate exhaustive conditional branches. For example, 2 variants × 2 values = 4 branches: ```ts 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' } ``` If 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. **INSTANCE_SWAP** — access swappable component instances: ```ts const icon = instance.getInstanceSwap('Icon') let iconCode if (icon && icon.type === 'INSTANCE') { iconCode = icon.executeTemplate().example } ``` **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. - **Signature:** `getSlot(propName: string): ResultSection[] | undefined` ```ts // Figma property "Content" must be type SLOT in component properties const content = instance.getSlot('Content') export default { example: figma.code`<Card>${content}</Card>`, // ... } ``` ### Interpolation in tagged templates When interpolating values in tagged templates, use the correct wrapping: - **String values** (`getString`, `getEnum`, `textContent`): wrap in quotes → `variant="${variant}"` - **Instance/section values** (`executeTemplate().example`): wrap in braces → `icon={${iconCode}}` - **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 - **Boolean bare props**: use conditional → `${disabled ? 'disabled' : ''}` ### Finding descendant layers When you need to access children that aren't exposed as component properties: | Method | Use when | |---|---| | `instance.getInstanceSwap('PropName')` | Figma property type is **INSTANCE_SWAP** (fixed swapped instance) | | `instance.getSlot('PropName')` | Figma property type is **SLOT** (freeform content region) | | `instance.findInstance('LayerName')` | You know the child layer name (no component property) | | `instance.findText('LayerName')` → `.textContent` | You need text content from a named text layer | | `instance.findConnectedInstance('id')` | You know the child's Code Connect `id` | | `instance.findConnectedInstances(fn)` | You need multiple connected children matching a filter | | `instance.findLayers(fn)` | You need any layers (text + instances) matching a filter | ### Nested configurable instances A 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. 1. **Check whether the child already has a Code Connect template** — use `get_code_connect_suggestions` or check existing `.figma.ts` files in the project. 2. **If no template exists, create one** for the child so it renders correctly both standalone and when nested. 3. **Reference the child from the parent** using `findInstance()` or `findConnectedInstance()`, then call `executeTemplate()`. ```ts // 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>`, // ... } ``` This 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. ### Nested component example For multi-level nested components or metadata prop passing between templates, see [advanced-patterns.md](references/advanced-patterns.md). ```ts const icon = instance.getInstanceSwap('Icon') let iconSnippet
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기