Skip to content

Commit 9b60564

Browse files
author
figma-bot
committed
Code Connect v1.5.0
1 parent d35c213 commit 9b60564

45 files changed

Lines changed: 3025 additions & 321 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1+
# Code Connect v1.5.0 (29 July 2026)
2+
3+
> [!WARNING]
4+
> Previously, Code Connect required framework-specific parsers for React, iOS, Android and Web Components. Late in 2025, we introduced a new [template API](https://developers.figma.com/docs/code-connect/template-api/) that removed framework requirements and allows users to more flexibly control how code snippets are rendered inside of Figma. Going forward, new users should opt for this template format and we recommend existing users to follow our [migration guide](https://developers.figma.com/docs/code-connect/templates-migration-guide/) to move to the new format. Following August 17th, 2026, we will no longer be updating or actively maintaining the legacy parsers.
5+
6+
7+
## Fixed
8+
9+
### Template files
10+
11+
- Fixed nested rendered examples being dropped or formatted incorrectly when interpolated directly or passed to the React, Swift, and Kotlin child-rendering helpers.
12+
- Migrated template files no longer include unused generated prop constants.
13+
14+
## Features
15+
16+
### Template files
17+
18+
- Added a `--delete` option to `figma connect migrate` that deletes source Code Connect files after they are successfully migrated.
19+
- Template files (TypeScript and JavaScript) now support importing local helper modules via relative paths (for example, `./shared-helpers`) to promote reuse of shared formatting and utility logic. Helper code is bundled into the published template so it can run standalone, and helpers may import other local helpers to organize shared logic across multiple files. Only relative imports within the project are supported (external packages are not), and helpers must be brought in with `import` syntax — `require` remains available for the Figma API itself. Helper code you don't actually use is left out of the published template, and if the bundled output exceeds the maximum template size, the CLI fails before publishing.
20+
21+
### General
22+
23+
- `figma connect preview` can now render a component in states beyond its default, and inspect its properties:
24+
- `figma connect preview <file> --inspect` prints the component's properties and variants — name, type, variant options, and default — without rendering a snippet.
25+
- `figma connect preview <file> --props Name=Value …` renders a single specific property combination. Pairs are space-separated arguments (quote a pair only when its name or value contains spaces, e.g. `"Has Icon Start=true"`). Property names and variant values are matched case-insensitively, unspecified properties keep their defaults, and an invalid variant value is reported along with the valid options. To target a property when two properties share a name but differ in type, prefix the pair with the type, e.g. `"BOOLEAN:textMsg=false" "TEXT:textMsg=Hello"`; the prefix is optional and only needed to disambiguate.
26+
- `figma connect preview <file> --all` renders every property combination of the component — the cartesian product of its variant and boolean properties. Requires a specific component file argument. Use `--max-combinations <number>` to render fewer combinations when the full set is large.
27+
128
# Code Connect v1.4.9 (6 July 2026)
229

330
## Fixed
@@ -25,6 +52,7 @@
2552
- Augmented the `getSlot` API: `getSlot('SlotName')` still renders the same way, and the returned value now also exposes `connectedInstances` (the connected instances directly in the slot). This lets you render a slot's connected children inline. For example `getSlot('body').connectedInstances.map((c) => c.executeTemplate().example)`.
2653

2754
### React & HTML
55+
2856
- Augmented the `figma.slot` API: `figma.slot('SlotName')` still maps the slot the same way, and you can now also write `figma.slot('SlotName').connectedInstances` in a `props` object to render the slot's code-connected instances inline. For example `props: { content: figma.slot('Content').connectedInstances }`.
2957

3058
# Code Connect v1.4.8 (8 June 2026)

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Code Connect
22

3+
> [!WARNING]
4+
> Previously, Code Connect required framework-specific parsers for React, iOS, Android and Web Components. Late in 2025, we introduced a new [template API](https://developers.figma.com/docs/code-connect/template-api/) that removed framework requirements and allows users to more flexibly control how code snippets are rendered inside of Figma. Going forward, new users should opt for this template format and we recommend existing users to follow our [migration guide](https://developers.figma.com/docs/code-connect/templates-migration-guide/) to move to the new format. Following August 17th, 2026, we will no longer be updating or actively maintaining the legacy parsers.
5+
36
Code Connect is a tool for connecting your design system components in code with your design system in Figma. When using Code Connect, Figma's Dev Mode will display true-to-production code snippets from your design system instead of autogenerated code examples. In addition to connecting component definitions, Code Connect also supports mapping properties from code to Figma enabling dynamic and correct examples. This can be useful for when you have an existing design system and are looking to drive consistent and correct adoption of that design system across design and engineering.
47

58
Code Connect is easy to set up, easy to maintain, type-safe, and extensible. The easiest way to get started is using **template files** — a framework-agnostic way to represent any code snippet, giving you full control over how components appear in Dev Mode. Code Connect also includes framework-specific integrations for React (and React Native), Storybook, HTML (e.g. Web Components, Angular and Vue), SwiftUI and Jetpack Compose.

cli/figma-types-no-require.d.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ declare module 'figma' {
2323
export type SlotSection = { type: 'SLOT'; guid?: string; propertyName: string }
2424
export type ErrorSection = { type: 'ERROR'; message: string; errorObject?: unknown }
2525
export type ResultSection = CodeSection | InstanceSection | SlotSection | ErrorSection
26+
export type ResultSectionList = Array<ResultSection | ResultSectionList>
2627

2728
export interface TemplateStringResult {
2829
sections: ResultSection[]
@@ -99,6 +100,7 @@ declare module 'figma' {
99100
name: string
100101
}): InstanceHandle | TextHandle | ErrorHandle | null
101102
__getPropertyValue__(name: string): string | boolean | ErrorHandle
103+
__getPropertyValueByType__(name: string, type: string): string | boolean | ErrorHandle
102104
__render__(): ResultSection[]
103105
__getProps__(): ResultSection[] | Record<string, unknown> | undefined
104106
__renderWithFn__(
@@ -192,12 +194,12 @@ declare module 'figma' {
192194

193195
helpers: {
194196
react: {
195-
renderProp(name: string, prop: FCCValue | ResultSection[]): TemplateStringResult | string
197+
renderProp(name: string, prop: FCCValue | ResultSectionList): TemplateStringResult | string
196198
renderChildren(
197-
prop: FCCValue | ResultSection[],
199+
prop: FCCValue | ResultSectionList,
198200
): ResultSection[] | string | number | boolean | TemplateStringResult
199201
renderPropValue(
200-
prop: FCCValue | ResultSection[],
202+
prop: FCCValue | ResultSectionList,
201203
): string | number | boolean | ResultSection[]
202204
stringifyObject(obj: unknown): string
203205
jsxElement(value: string): { $value: string; $type: 'jsx-element' }
@@ -207,17 +209,17 @@ declare module 'figma' {
207209
templateString(value: string): { $value: string; $type: 'template-string' }
208210
reactComponent(value: string): { $value: string; $type: 'react-component' }
209211
array(value: FCCValue[]): { $value: FCCValue[]; $type: 'array' }
210-
isReactComponentArray(prop: unknown): boolean
212+
isReactComponentArray(prop: unknown): prop is ResultSectionList
211213
}
212214
swift: {
213215
renderChildren(
214-
children: ResultSection[] | string | undefined,
216+
children: ResultSectionList | string | undefined,
215217
prefix: string,
216218
): ResultSection[]
217219
}
218220
kotlin: {
219221
renderChildren(
220-
children: ResultSection[] | string | undefined,
222+
children: ResultSectionList | string | undefined,
221223
prefix: string,
222224
): ResultSection[]
223225
}

cli/figma-types.d.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ declare module 'figma' {
2020
export type SlotSection = { type: 'SLOT'; guid?: string; propertyName: string }
2121
export type ErrorSection = { type: 'ERROR'; message: string; errorObject?: unknown }
2222
export type ResultSection = CodeSection | InstanceSection | SlotSection | ErrorSection
23+
export type ResultSectionList = Array<ResultSection | ResultSectionList>
2324

2425
export interface TemplateStringResult {
2526
sections: ResultSection[]
@@ -96,6 +97,7 @@ declare module 'figma' {
9697
name: string
9798
}): InstanceHandle | TextHandle | ErrorHandle | null
9899
__getPropertyValue__(name: string): string | boolean | ErrorHandle
100+
__getPropertyValueByType__(name: string, type: string): string | boolean | ErrorHandle
99101
__render__(): ResultSection[]
100102
__getProps__(): ResultSection[] | Record<string, unknown> | undefined
101103
__renderWithFn__(
@@ -189,12 +191,12 @@ declare module 'figma' {
189191

190192
helpers: {
191193
react: {
192-
renderProp(name: string, prop: FCCValue | ResultSection[]): TemplateStringResult | string
194+
renderProp(name: string, prop: FCCValue | ResultSectionList): TemplateStringResult | string
193195
renderChildren(
194-
prop: FCCValue | ResultSection[],
196+
prop: FCCValue | ResultSectionList,
195197
): ResultSection[] | string | number | boolean | TemplateStringResult
196198
renderPropValue(
197-
prop: FCCValue | ResultSection[],
199+
prop: FCCValue | ResultSectionList,
198200
): string | number | boolean | ResultSection[]
199201
stringifyObject(obj: unknown): string
200202
jsxElement(value: string): { $value: string; $type: 'jsx-element' }
@@ -204,17 +206,17 @@ declare module 'figma' {
204206
templateString(value: string): { $value: string; $type: 'template-string' }
205207
reactComponent(value: string): { $value: string; $type: 'react-component' }
206208
array(value: FCCValue[]): { $value: FCCValue[]; $type: 'array' }
207-
isReactComponentArray(prop: unknown): boolean
209+
isReactComponentArray(prop: unknown): prop is ResultSectionList
208210
}
209211
swift: {
210212
renderChildren(
211-
children: ResultSection[] | string | undefined,
213+
children: ResultSectionList | string | undefined,
212214
prefix: string,
213215
): ResultSection[]
214216
}
215217
kotlin: {
216218
renderChildren(
217-
children: ResultSection[] | string | undefined,
219+
children: ResultSectionList | string | undefined,
218220
prefix: string,
219221
): ResultSection[]
220222
}

cli/npm_catalog.toml

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,17 @@
100100
"@babel/template" = "7.28.5"
101101
"@babel/traverse" = "7.28.5"
102102
"@babel/types" = "7.28.5"
103-
"oxlint" = "1.67.0"
104-
"oxlint-tsgolint" = "0.23.0"
103+
"oxlint" = "1.72.0"
104+
"oxlint-tsgolint" = "0.24.0"
105+
"oxlint-plugin-eslint" = "1.72.0"
105106
"eslint" = "9.37.0"
106107
"eslint-config-prettier" = "^9.1.0"
107108
"eslint-plugin-clsx" = "^0.0.12"
108109
"eslint-plugin-import" = "^2.32.0"
109110
"eslint-plugin-jest" = "^28.8.3"
110111
"eslint-plugin-react" = "^7.37.5"
111112
"eslint-plugin-react-hooks" = "^5.2.0"
113+
"eslint-plugin-react-perf" = "^3.3.3"
112114
"eslint-plugin-simple-import-sort" = "^12.1.1"
113115
"eslint-plugin-unused-imports" = "^4.1.4"
114116
"eslint-import-resolver-typescript" = "^4.4.4"
@@ -117,7 +119,7 @@
117119
"@eslint/js" = "9.37.0"
118120
"@eslint/config-helpers" = "^0.4.0"
119121
"@vitest/eslint-plugin" = "^1.6.16"
120-
"electron" = "42.4.1"
122+
"electron" = "43.1.1"
121123
"@typescript-eslint/eslint-plugin" = "8.59.1"
122124
"@typescript-eslint/parser" = "8.59.1"
123125
"@typescript-eslint/project-service" = "8.59.1"
@@ -141,6 +143,9 @@
141143
"jest-cli" = "^29.7.0"
142144
"jest-junit" = "16.0.0"
143145
"ts-jest" = "^29.4.9"
146+
"@testing-library/dom" = "10.4.1"
147+
"@testing-library/jest-dom" = "6.9.1"
148+
"@testing-library/react" = "16.3.2"
144149
"@testing-library/user-event" = "14.6.1"
145150
"c8" = "^11.0.0"
146151
"just-bash" = "^2.10.2"
@@ -175,6 +180,7 @@
175180
"@storybook/components" = "8.5.1"
176181
"@storybook/core" = "8.5.1"
177182
"@storybook/core-events" = "8.5.1"
183+
"@storybook/csf" = "0.1.12"
178184
"@storybook/csf-tools" = "8.5.1"
179185
"@storybook/experimental-addon-test" = "8.5.1"
180186
"@storybook/instrumenter" = "8.5.1"
@@ -194,24 +200,30 @@
194200
"@tailwindcss/postcss" = "4.1.3"
195201
"@tailwindcss/vite" = "4.1.3"
196202
"tailwindcss" = "4.1.3"
197-
"@tanstack/react-router" = "1.130.0"
198-
"@tanstack/react-router-devtools" = "1.130.0"
203+
"@tanstack/history" = "^1.162.0"
204+
"@tanstack/react-router" = "^1.170.16"
205+
"@tanstack/react-router-devtools" = "^1.167.0"
206+
"@tanstack/react-virtual" = "3.13.18"
207+
"@tanstack/router-generator" = "^1.167.0"
208+
"@tanstack/virtual-file-routes" = "^1.162.0"
199209
"@terrazzo/cli" = "2.1.0"
210+
"@terrazzo/parser" = "2.1.0"
200211
"@terrazzo/plugin-css" = "2.1.0"
201212
"@terrazzo/plugin-tailwind" = "2.1.0"
202213
"webpack" = "5.91.0"
203214
"webpack-cli" = "5.1.4"
204215
"modal" = "0.7.2"
205216
"@axe-core/playwright" = "4.11.0"
206217
"@bazel/runfiles" = "^6.3.1"
207-
"@figma/plugin-typings" = "1.121.0"
218+
"@figma/plugin-typings" = "1.130.0"
208219
"@figma/widget-typings" = "1.12.1"
209220
"@formatjs/icu-messageformat-parser" = "^2.11.2"
210221
"@modelcontextprotocol/ext-apps" = "1.0.1"
222+
"@modelcontextprotocol/node" = "2.0.0-beta.2"
211223
"@modelcontextprotocol/sdk" = "1.27.0"
224+
"@modelcontextprotocol/server" = "2.0.0-beta.2"
212225
"@opentelemetry/api" = "^1.9.0"
213226
"@sentry/cli" = "2.58.3"
214-
"@tanstack/react-virtual" = "3.13.18"
215227
"@types/jsdom" = "^21.1.7"
216228
"@types/mocha" = "10.0.10"
217229
"@types/node" = "22.19.21"
@@ -233,15 +245,18 @@
233245
"jsdom" = "27.4.0"
234246
"knip" = "^5.27.3"
235247
"lightningcss" = "1.32.0"
236-
"mediabunny" = "1.34.4"
248+
"mediabunny" = "1.50.3"
237249
"mocha" = "10.8.2"
238250
"mocha-junit-reporter" = "2.2.1"
239251
"postcss" = "8.5.2"
240-
"prettier" = "3.6.2"
252+
"prettier" = "3.9.3"
241253
"puppeteer" = "24.36.1"
242254
"react-dom" = "18.3.1"
243-
"react-redux" = "8.0.5"
255+
"react-redux" = "8.1.3"
244256
"react" = "18.3.1"
257+
"redux" = "4.0.4"
258+
"redux-optimist" = "0.0.2"
259+
"redux-thunk" = "2.4.2"
245260
"sharp" = "0.34.5"
246261
"@img/sharp-darwin-arm64" = "0.34.5"
247262
"@img/sharp-linux-x64" = "0.34.5"

cli/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@figma/code-connect",
3-
"version": "1.4.9",
3+
"version": "1.5.0",
44
"description": "A tool for connecting your design system components in code with your design system in Figma",
55
"keywords": [],
66
"author": "Figma",
@@ -81,7 +81,6 @@
8181
"@babel/types": "7.28.5",
8282

8383

84-
8584
"@storybook/csf-tools": "8.5.1",
8685
"@types/cross-spawn": "^6.0.6",
8786
"@types/jest": "^29.5.13",
@@ -110,6 +109,7 @@
110109
"compare-versions": "^6.1.0",
111110
"cross-spawn": "^7.0.3",
112111
"dotenv": "^16.3.1",
112+
"esbuild-wasm": "0.27.3",
113113
"fast-fuzzy": "^1.12.0",
114114
"find-up": "^5.0.0",
115115
"glob": "^11.0.4",

0 commit comments

Comments
 (0)