# Code Connect

Auto-loaded when working in `packages/components/src/figma/**` (`*.figma.ts`, `*.figma.batch.ts`, `*.figma.batch.json`).

Template files connect Forge UI components to Figma Dev Mode snippets. Read the full guide before making changes:

- `docs/internal/practices/code-connect.md` — complete workflow, mapping patterns, publishing, troubleshooting

## Pattern summary

Each `.figma.ts` file follows this structure (see `Button.figma.ts` as the canonical example):

1. **Metadata comments** — `// url=`, `// source=`, `// component=` at the top (required)
2. **`figma` import** — `import figma from 'figma'` (template API, not a runtime import)
3. **Instance handle** — `const instance = figma.selectedInstance`
4. **Property mappings** — `getEnum`, `getBoolean`, `getInstanceSwap`, `findText`, `findInstance`
5. **Default export** — `{ id, imports, example }` with optional `metadata`

## Key rules

- **Enum renaming** — pass a mapping object to `getEnum` when Figma and code names differ; list all values explicitly
- **Boolean-as-variant** — Figma VARIANT properties with `"true"`/`"false"` string values use `getEnum`, not `getBoolean`; map `"false"` to `undefined`; **always** render via `figma.helpers.react.renderProp` — never `isDisabled={${isDisabled}}` (produces `isDisabled={}` when undefined)
- **Instance swap** — use `getInstanceSwap` (not `findInstance`) for designer-swappable slots; call `.executeTemplate()` before interpolating; prefer `metadata.props.componentName` over raw `.example` for icon slots
- **Runtime states excluded** — `isHovered`, `isFocused`, `isPressed`, `isLoading` are runtime-managed; never map them
- **Falsy → `undefined`** — default or falsy values map to `undefined` so they don't clutter the snippet
- **Compound dot notation** — render sub-components as `Button.Label`, `Button.Icon`, not bare `Label`/`Icon`
- **`imports` array** — use `@cdx-ui/components` import path; Figma deduplicates identical strings
- **Nestable metadata** — leaf components (icons, badges) set `metadata: { nestable: true, props: { componentName } }`
- **Batch pattern** — for large sets with identical code shapes (icons), use `.figma.batch.ts` + `.figma.batch.json` with `figma.batch.name`/`figma.batch.id`
- **Publish** — `pnpm figma:publish` locally; CI publishes on merge to `main`
